Jules
Jules

Reputation: 7774

Obj-C, Memory leak confusion

I'm using a NSMutable String to gain a string back from a database query. I've assigned the variable with @"" and then populate if found from the database. I've tried adding autorelease / release but this causes problems with references to the database call.

Can someone point out my error ?

I would have typed this code but I felt the analyzer arrows were useful.

enter image description here

Upvotes: 0

Views: 76

Answers (2)

andyvn22
andyvn22

Reputation: 14824

strDBAppVer is first set to [NSMutableString stringWithString:@""], which is reasonable, memory-wise. However, later, you completely re-set the variable to a whole different object, created by alloc/initWithUTF8String:, making strDBAppVer sometimes point to an already-autoreleased object, and sometimes (when the if statement is true) point to an object with retain count +1.

That's why there's a leak but releasing causes issues. If the if statement is true, you've set your variable to point to an object with +1 count, and if it's false, you've set your variable to point to an entirely different object with 0 count.

This looks to me like confusion about mutable strings. Are you aware that, at least in the code posted, you don't actually mutate strDBAppVer? Try this instead:

NSString* strDBAppVer = @"";

Then, inside your if statement,

strDBAppVer = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statementAppVer,0)];
//Now, realizing that strDBAppVer has just been reassigned to point
//to an entirely new object, one created with alloc/init, and therefore one that
//needs to be released,
[strDBAppVer autorelease];

Note the autorelease is only inside the if statement, so it doesn't accidentally overrelease your original value of @"". (Since constant strings shouldn't be released.)

Upvotes: 1

Obliquely
Obliquely

Reputation: 7072

You're creating an autoreleased NSMutableString and assigning the pointer strDBAAppVer to point to it. But then you throw away the reference to that object, and get the pointer strDBAppVer to point to a new object, an NSString with a retain count of 1.

What I think you want is inside your if statement is something like this:

NSString* databaseField = [[NSString alloc] initWithUTF ...etc.]
[strDBAppVer setString: databaseField];
[databaseField release];

Upvotes: 2

Related Questions