Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum

View Single Post
Old 03-24-2009, 12:08 PM   #5 (permalink)
Kalimba
Pro. Game Developer
iPhone Dev SDK Supporter
 
Join Date: Feb 2009
Location: żLa Islas Hermosas?
Posts: 2,178
Default

Code:
// Build a section/row list from the alphabetically ordered word list
- (void) createSectionList
{
	sectionArray = [[NSMutableArray alloc] init];
	// Build an array with 26 sub-array sections
	for (int i = 0; i < 26; i++) [sectionArray addObject:[[NSMutableArray alloc] init]];	
	// the line above will normally cause a leak
	// Add each word to its alphabetical section
	
	for (NSString *cities in listData)
	{
		if ([word length] == 0) continue;
		// determine which letter starts the name
		NSString *firstletter = [[word substringToIndex:1] uppercaseString];
		NSRange range = [ALPHA rangeOfString:firstletter];
		// Add the name to the proper array
		[[sectionArray objectAtIndex:range.location] addObject:city]; 
	} 
}
It looks here like you're creating a 2-dimensional array by allocating one array (sectionArray), then allocating individual arrays as elements of that first array. On the offending line, the [[NSMutableArray alloc] init] returns instances with retaincount (rc) = 1, and adding it to the array makes rc=2. In your dealloc method, you release sectionArray, which automatically sends a release to all entries in the array, but that will only make rc=1 in those array objects, thus causing a leak.

You can fix this in at least two different ways. (1) Before you release sectionArray, you can iterate it and manually call release on each element, or (2) change the [[NSMutableArray alloc] init] in your code to [[[NSMutableArray alloc] init] autorelease]. (Note: I usually choose the latter approach, for reasons obvious. )

Code:
- (void)dealloc
{
	[super dealloc];	
	[sectionArray release];
	// just a style note here - typically you clean up everything in your class BEFORE calling the [super dealloc]
}

Code:
- (NSMutableArray *)grabCitiesWorld:(NSString *)country
{
	NSMutableArray *cities = [[NSMutableArray alloc] init];
	NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"CityData.sqlite"];	
	
    if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {				
		NSString *longsql =  [NSString stringWithFormat:@"SELECT city FROM %@ where country = '%@' ORDER BY City", table, country];
		const char *sql = [longsql UTF8String];
   		sqlite3_stmt *statement;		
		if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
            while (sqlite3_step(statement) == SQLITE_ROW) {     
				NSString *cityname = [NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 0)];
							[cities addObject:cityname];					
            }
        }
        // "Finalize" the statement - releases the resources associated with the statement.
        sqlite3_finalize(statement);
    } else {
        // Even though the open failed, call close to properly clean up resources.
        sqlite3_close(database);
        NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(database));
        // Additional error handling, as appropriate...
    }
	sqlite3_close(database);
	return cities;
	[cities release];
	// BIG problem here
}
Hopefully, the problem here is obvious now. You're returning from the function before the [cities release] executes, so the release is never done. In a function, once any return statement it hit, the function ends. Period.

But you're thinking that you've allocated an array in this function -- how do you return a valid array, yet clean it up properly? Like this:
Code:
	return [cities autorelease];
This will return an array that the caller can use, but will automatically be released via the autorelease pool and not cause a leak.

Hopefully this helps. Let us know how things progress.
Kalimba is offline   Reply With Quote
 

» Advertisements
» Stats
Members: 158,684
Threads: 89,158
Posts: 380,400
Top Poster: BrianSlick (7,110)
Welcome to our newest member, Samuveljisri
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 06:53 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.