some questions about how to use momery by redis - memory

I am rewriting the redis source code.
below:
c->argv = zmalloc(sizeof(robj*)*c->multibulklen);
...
c->argv[c->argc++] =
createStringObject(c->querybuf+pos,c->bulklen);
The part of code parses the parameters of a statement.for example: (set abc 123) the content of c->argv is c->argv[0] = set, c->argv[1] = abc, c->argv[2] = 123.
Storing the data into dict :
int dictAdd(dict *d, void *key, void *val)
{
dictEntry *entry = dictAddRaw(d, key);
if (!entry) return DICT_ERR;
dictSetVal(d, entry, val);
return DICT_OK;
}
key in dictAdd is "abc". val is "123".
The command--set abc 123 is finished.Then the momery used by c->argv is going to be freed.
void resetClient(redisClient *c) {
redisCommandProc *prevcmd = c->cmd ? c->cmd->proc : NULL;
freeClientArgv(c);
DICT_NOTUSED(prevcmd);
c->multibulklen = 0;
c->bulklen = -1;
}
A error occurs to me when I run the second command, returning "abc" instead of "123".
I find that the memory address of "123" is replaced by "abc" included in "get abc".
Any help would be appreciated.

I have solved this problem. because I don't add the object reference count.If the object reference count is 2,the memory is not going to be freed.

Related

Expected method to read array element not found on object of type NSDictionary*

I know there's a lot of questions like this around, but I think my situation's a tad different.
int i = 0;
while (_data[#"VerticalState%i", i] != nil) {
// do things
i++;
}
For example, one 'level' that has 3 VerticalState properties will be implemented as such: VerticalState0, VerticalState1, VerticalState2.
I want to read in those values using that while loop condition above, and it should stop when i = 3. How can I make the idea of that code above work (with some other configuration obviously). FYI, _data is an NSDictionary* instance variable, already loaded with the plist information.
You appear to want to create a dictionary key from a string format. You need to use NSString stringWithFormat:.
while (_data[[NSString stringWithFormat:#"VerticalState%i", i]] != nil) {
Though it would be better to write the loop like this:
int i = 0;
while (1) {
NSString *key = [NSString stringWithFormat:#"VerticalState%i", i];
id value = _dict[key];
if (value) {
// do things
i++;
} else {
break;
}
}

Two objects pointing to same address is not working. e.g. newArray = oldArray

I am using the following type of object reference copy functionality throughout my iOS application.
e.g. objectA = objectB;
When you perform operation/changes on objectA it would automatically get reflected in objectB. You do not need to copy objectA to objectB again to reflect the changes in objectB, as they are pointing/referring to same location(address).
The problem is it was working fine till the iOS 8.2 however it seems to not work in iOS 8.3 at all.
Following is one of the code snippet which is not working correctly.
NSMutableDictionary *fieldObj = self.theData[indexPath.section ][indexPath.row];
// Adding text to data array
[fieldObj setObject:textField.text.stringByStrippingHTML forKey:#"value"];
NSLog(#"Line 1 \n%#",fieldObj);
NSLog(#"Line 2 \n%#",self.theData[indexPath.section][indexPath.row]);
From Above code Line 1 and Line 2 are giving same output upto iOS 8.2.
Line 1
{
name = Name;
required = NO;
type = 4;
value = asdfasdfasdfasdfsad;
}
Line 2
{
name = Name;
required = NO;
type = 4;
value = asdfasdfasdfasdfsad;
}
however in iOS 8.3 they are giving the different outputs.
Line 1
{
name = Name;
required = NO;
type = 4;
value = asdfasdfasdfasdfsad;
}
Line 2
{
name = Name;
required = NO;
type = 4;
value = "";
}
Am I doing anything wrong here?
If not does anyone know about the issue and how to solve it?
EDIT:
Sorry for the above misleading question, the reason behind above problem I found is that the indexPathForItemAtPoint:(CGPoint) is returning wrong indexPath in iOS 8.3 only.
The code I have used is as follow:
// retrieve indexpath from uitextfield
CGPoint pos = [textField convertPoint:CGPointZero toView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:pos];
The above code is working fine upto iOS versions 8.2.
I made and easy snippet that I think it will reflect you actual situation: an immutable container with mutable container inside.
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
NSArray * array = #[#{#"KEY" : #"OLD" }.mutableCopy];
NSMutableDictionary * dict = array.firstObject;
[dict setObject:#"NEW" forKey:#"KEY"];
NSLog(#"Mutated dict %#",dict);
NSLog(#"From original source %#",array.firstObject);
}
return 0;
}
Everything seems to work as expected, are you sure that you are doing something somewhere else?
2015-04-15 08:37:09.740 prova[912:117578] Mutated dict {
KEY = NEW; } 2015-04-15 08:37:09.741 prova[912:117578] From original source {
KEY = NEW; }
Also the both object have the same address as expected:
(lldb) expression dict (__NSDictionaryM *) $2 = 0x00000001003004a0 1
key/value pair (lldb) expression array.firstObject (__NSDictionaryM *)
$3 = 0x00000001003004a0 1 key/value pair
Try to set it as below.
NSMutableDictionary *fieldObj =
[
self.theData[indexPath.section ][indexPath.row]
mutableCopy
];
& check. I believe it will work.

Save int variable to Parse Object

I have a variable int and i want to save this to a PFObject. Whenever I try I get the error:
incompatible integer to point value from int to id.
I can add a normal int which is not in a variable by doing.
PFObject* object = [PFObject objectwithclassname:#"test"];
object[#"score"] = #30;
This works fine, and also I can add a string and it will work. It is when I try this that it does not work.
int test = 10;
object[#"score"] = test;
Anyone know?
The syntax is:
object[#"score"] = #(test);
Variables of type int are no (Objective-C) objects. You use the keyed subscription protocol for assignment. It only takes objects. Basically this is done:
[object setObject:test forKeyedSubscript:#"score"]; // Error: test is no object
So the solution is to put the non-object typed int into an object (boxing). You can do this with rmaddy's solution (boxed expression) or more explicit for a better understanding:
object[#"score"] = [NSNumber numberWithInt:test];

CFNumber macro for constants

Pretty sure the answer is No on this one, but it's painful enough I have to ask: Is there a CFNumber equivalent to CFString's CFSTR macro? To avoid this sort of thing:
char one = 1;
CFNumberRef cfONE = CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &one);
if (cfONE != NULL) {
... finally I can compare something to the number 1! ...
CFRelease(cfONE);
} else {
// not likely, but possible, if you really want to be conservative
}
Note that I'm not using Objective-C in this particular code.
Eric
If you plan on using this function multiple times, you could the static modifier and stop worrying about deallocation:
static CFNumberRef cfONE = NULL;
if (cfONE == NULL) {
static char one = 1;
cfONE = CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &one);
assert (cfONE != NULL); // Oh no, destroy the world!
}
// ... finally I can compare something to the number 1! ...
So long as you have static, the static analyzer will leave you alone on the leak issue since it is an expected constant size memory allocation, O(1) rather than O(n) where n is the number of executions.
There are several ways to make this a macro. I came up with this lazy one:
#define CFNUMDEF(name, type, numberType, value) \
static CFNumberRef name = NULL; \
if ( name == NULL) { \
static type val = value ;\
name = CFNumberCreate(kCFAllocatorDefault, numberType , &val);\
assert ( name != NULL); \
}
CFNUMDEF(cfONE, char, kCFNumberCharType, 1);
// ... finally I can compare something to the number 1! ...
CFSTR is a little different from your case
CFSTR() allows creation of compile-time constant CFStringRefs; the argument
should be a constant C-string.
CFSTR(), not being a "Copy" or "Create" function, does not return a new
reference for you. So, you should not release the return value. This is
much like constant C or Pascal strings --- when you use "hello world"
in a program, you do not free it.
Where as the object you create with CFNumberCreate will be owned by the caller so you may still want to keep the word create in the name to make this clear.
You could always make a helper function just to avoid passing the same arguments over and over
CFNumberRef PSNumberCreateWithChar(x)
{
return CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &x);
}
CFNumberRef and NSNumber are toll free bridged so you can use the NSNumber literal syntax and cast the result.

NSDictionary objectForKey returns wrong value

I'm trying to use a dictionary which I got as a JSON response from my server. When I print the description of the dictionary, everything is in order
Printing description of dict:
{
category = 1;
code = 1;
name = "xxxx";
pictureUrl = "xxxx";
sessionId = xxx;
status = 0;
}
I need the "code" value, and when I use objectForKey:#"code" to get it, I get a wrong value:
int code = [NSDictionary objectForKey:#"code"];
After this i print out the value of code and its something like 3483765348, which is very, very wrong.
Why is this happening?
The object returned is an NSNumber and not an int (which isn't an object).
If you want the int value try this
int code = [[myDictionary objectForKey:#"code"] intValue];
Try the following code which will be use to solve your issue.. As per your code it returns only value you have to convert it to int value.Use this piece of code
int code = [[NSDictionary objectForKey:#"code"]intValue];
Hope this Helps !!!
-objectForKey: doesn't return an int, but an object instead (in your case of type NSNumber).
NSNumber *code = [myDict objectForKey:#"code"];
NSInteger codeInteger = [code integerValue];
int code = [[yourResultingDictionary objectForKey:#"code"] intValue];
I think it will be helpful to you.
The object key returns only for array values, so you will use value for key path.
user_idstr = [tweet valueForKeyPath:#"properties.user_id"];

Resources