Memory Leaks

Discussion in 'iOS Programming' started by membernamej, Aug 5, 2009.

  1. membernamej macrumors newbie

    Joined:
    Aug 5, 2009
    #1
    I am having some memory issues with this method. courseNames, iDString and tempData are leaking, but nameString does not seem to be leaking. Can someone explain to me how to prevent this from happening

    Code:
    +(NSMutableArray *)selectNamesAndID{
    	NSString *query = [[NSString alloc] initWithFormat: @"SELECT Name, ID FROM Courses"];
    	[query autorelease];
    	sqlite3_stmt *statement;
    	NSMutableArray *courseNames = [[NSMutableArray alloc] init];
    	[courseNames autorelease];
    	int result = (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL));
    	NSString *nameString;
    	NSString *iDString;
    	NSArray *tempData;
    	while(sqlite3_step(statement) == SQLITE_ROW){
    		char *nameChar = (char *)sqlite3_column_text(statement, 0);
    		nameString = [[NSString alloc] initWithUTF8String:nameChar];
    		int iDInt  = sqlite3_column_int(statement, 1);
    		iDString = [[NSString alloc] initWithFormat:@"%d", iDInt];
    		tempData = [[NSArray alloc] initWithObjects:nameString, iDString, nil];
    		[tempData autorelease];
    		[courseNames  addObject:tempData];
    		[tempData release];
    		[nameString release];
    		[iDString release];
    	}
    	sqlite3_finalize(statement);
    	
    	return courseNames;
    }
     
  2. Luke Redpath macrumors 6502a

    Joined:
    Nov 9, 2007
    Location:
    Colchester, UK
    #2
    Well the first thing that jumps out is you are auto-releasing objects when it would be much simpler and more deterministic to simply release them once you are done with them. I'd also avoid heavy use of autorelease within the loop as this could cause the autorelease pool to increase in size rapidly.

    I also notice you are over-releasing tempData, by first calling autorelease on it then releasing it once you've used it. Remove the autorelease call.
     
  3. wlh99 macrumors 6502

    Joined:
    Feb 7, 2008
    #3
    I'm just reading this now:
    http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.pdf

    It is an important read. I'm no expert yet, but this is what I think.

    The only object you should autorelease is courseNames. This is because you own it and are responsible to release it, but can't release it until it is done being used by the object you are returning it to. Everything else release as soon as you are done with it. Release query just before the return.

    Get rid of all the other autoreleases.

    I think objects in an Array will be retained by the Array. tempData autoreleased, so until the pool releases it idString and nameString will be retained as well. This also means that you can release iDString and nameString as soon as they are added to tempData.

    As I said I'm not an expert yet, so if someone thinks I'm wrong, let me know.
     
  4. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #4
    You should be using FMDB, which wraps sqlite.
     

Share This Page