views:

91

answers:

2

There's a memory leak in my program and because I'm not well versed in C (created a function in my Objective-C class to load strings from a SQLite database). Can anyone spot my blunder? Thank you:

static int MyCallback(void *context, int lCount, char **values, char **columns){

NSMutableArray *sqlRawStrings = (NSMutableArray *)context;
for (int i = 0; i < lCount; i++) {
    const char *nameCString = values[i];
    if (nameCString != NULL) {
        [sqlRawStrings addObject:[NSString stringWithUTF8String:nameCString]];
    }
} 

return SQLITE_OK;

}

All this is called earlier here:

int numberA = [loadBundleNumber intValue];
char str1[130] = "select ";
for(int i = 7; i <7 + numberA; i++){
    str1[i] = 'a';
}
char str2[20] = " from puzzles";
strcat(str1,str2);

NSString *file = [[NSBundle mainBundle] pathForResource:@"finalPuzzles" ofType:@"db"];
sqlite3 *database = NULL;
if (sqlite3_open([file UTF8String],&database) == SQLITE_OK) {
    sqlite3_exec(database, str1, MyCallback, sqlRawStrings, NULL);
}
sqlite3_close(database);

Thanks

A: 

More comments than answers as I don't see how you're leaking memory just yet (not enough points to comment yet). How are you observing that there is a memory leak? Can you see what's inside the object that is being leaked and work back through its allocation stack trace to see what it is?

Also can you supply the declaration for sqlRawStrings?

As an aside, I think that the way you're building your strings could be improved. Consider using sprintf. You might also want to consider using a .mm file instead of .m and then you'll get C++ capability; the std::string class could help you.

Finally, do not close something unless you've successfully opened it i.e. the "sqlite3_close" should be within the same block as sqlite3_exec.

'hope that this is helpful.

Christopher Hunt
Thanks for your comment Chris. sqlRawStrings is an instance variable that is declared when the program is loaded: sqlRawStrings = [[NSMutableArray alloc] init]; I learned of the memory leaks via Apple's Instruments tool.
Salvi
Have you tried eliminating the callback from being called to see if the memory leak disappears i.e. have you isolated the leak? (try passing NULL as the callback to the exec function)
Christopher Hunt
Also I presume that your code is executing within a runloop? If not then your stringWithUTF8String and some other methods will leak as their autorelease will never been realised.
Christopher Hunt
I did exactly that and I figured out where the program was leaking. Really appreciate it!
Salvi
Would you mind upvoting my response then and/or claiming it as the answer; and possibly editing your question to elaborate on what the answer is? Thanks.
Christopher Hunt
A: 

Best guess is that sqlRawStrings is never released and so neither is anything added to it.

Chuck