开发者

Need help in finding a memory leak in copying Sqlite Database to Mutable array

I seem to be having a 1.19 KB leak somewhere in the following code. opening up the call tree in instruments, I have narrowed down the leaks to the following:

61.开发者_JS百科8% of the leaks are coming from +[NSString stringWithUTF8String:]

38.1% of the leaks are coming from +[NSNumber numberWithDouble:]

-(void) readMinesFromDatabase 
{
    NSLog(@" Setup the database object");
    sqlite3 *database;

    // Init the  Array
    northernMines = [[NSMutableArray alloc] init];
    nCentralMines = [[NSMutableArray alloc] init];
    centralMines = [[NSMutableArray alloc] init];
    southernMines = [[NSMutableArray alloc] init];
    //NSLog(@" pre if statement");
    // Open the database from the users filessytem
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) 
{
    // Setup the SQL Statement and compile it for faster access
    const char *sqlStatement = "SELECT * FROM mines";
    //NSLog(@"pre 2nd if statement");
    sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) != SQLITE_OK) 
{
        NSLog( @"Error: Failed to prepare stmt with message %s", sqlite3_errmsg(database));
    }
    else 
{
        // Loop through the results and add them to the feeds array
        NSLog(@"pre loop");
        while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
            NSString *name;
            NSString *com;
            NSString *county;
            NSNumber *lat;
            NSNumber *longit;
            // Read the data from the result row
            //deals with null strings in the name and commodity fields of the database
            //NSLog(@"ered the loop");
            if (sqlite3_column_text(compiledStatement, 3) != NULL) {
                name = [NSString  stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
            } 
            else {
                name = @"";
            }
            if (sqlite3_column_text(compiledStatement, 10) != NULL) {
                com = [NSString  stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 10)];
            } 
            else {
                com = @"";
            }
            //latitude and longitudes
            lat = [NSNumber numberWithDouble:(double )sqlite3_column_double(compiledStatement, 4)];
            longit = [NSNumber numberWithDouble:(double )sqlite3_column_double(compiledStatement, 5)];
            //NSLog(@"long %@",longit);
            // Create a new  object with the data from the database
            Mine *mine = [[Mine alloc] initWithMineName:name latitudeInitial:lat longitudeInitial:longit commodity:com];

            // Add the object to the animals Array
            county = [NSString  stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 8)];

            if([county isEqualToString:@"Butte"] || [county isEqualToString:@"Plumas"] || [county isEqualToString:@"Yuba"] || [county isEqualToString:@"Sierra"])
            {
                [northernMines addObject:mine];
            }
            else if([county isEqualToString:@"Nevada" ]|| [county isEqualToString:@"Placer"] || [county isEqualToString:@"El Dorado"] || [county isEqualToString:@"Sutter"])
            {
                [nCentralMines addObject:mine];

            }
            else if([county isEqualToString:@"Amador"] || [county isEqualToString:@"Sacramento"] || [county isEqualToString:@"Calaveras"] || [county isEqualToString:@"San Joaquin"] || [county isEqualToString:@"Stanislaus"])
            {
                [centralMines addObject:mine];
            }
            else if([county isEqualToString:@"Tuolumne"] ||[county isEqualToString:@"Mariposa"] || [county isEqualToString:@"Madera"] || [county isEqualToString:@"Merced"])
            {
                [southernMines addObject:mine];
            }
            else
            {

            }
            [mine release];
            //[name release];
            //[com release];
            //[county release];                        
            //[lat release];
            //[longit release];

        }
        NSLog(@"done with loop");
        //[mines addObject:@"nil"];

    }
    // Release the compiled statement from memory
    sqlite3_finalize(compiledStatement);


}
sqlite3_close(database);
}

the mine object implementation file is:

#import "Mine.h"

@implementation Mine
@synthesize mineName, latitudeInitial, longitudeInitial, commodity;
-(id)initWithMineName:(NSString *)n latitudeInitial:(NSNumber *)l longitudeInitial:(NSNumber *)g commodity:(NSString *)c 
{
    self.mineName = n;
    self.latitudeInitial = l;
    self.longitudeInitial = g;
    self.commodity = c;
    return self;
}

@end


Well, it is a little hard to tell because of the indentation where the function ends (is this the entire function?) but I believe you are forgetting to release the 4 arrays that you are allocating at the beginning of the function. By leaking the arrays you are also leaking their contents.


Edit - for the initializer code you added:

I am not sure if this has anything to do with the memory leaks but I noticed that the initializer is not implemented correctly:

  • you should call init on super and update self (more details here)

  • of this I am not 100% sure, but I think you should not send messages (call methods) to the current object from inside the init method, and by using the dot notation you are actually calling the setter methods (but again, I am not really sure of this one)

I suppose that the properties are declared as (retain) and that you release them in the dealloc method. Which would be correct.

I can't really see anything else wrong with the code you showed. Maybe the problem is not exactly here (just an idea).


Edit 2 - example initializer

You should spend some time reading the Apple documentation, it has plenty of examples.

Here is my version (I hope it doesn't have too many mistakes):

-(id)initWithMineName:(NSString *)n latitudeInitial:(NSNumber *)l longitudeInitial:(NSNumber *)g commodity:(NSString *)c {

    // Assign self to value returned by super's designated initializer

    // Designated initializer for NSObject is init

    self = [super init];

    if (self) {

        mineName = [n retain];
        latitudeInitial = [l retain];
        longitudeInitial = [g retain];
        commodity = [c retain];

    }

    return self;
}


Just a thought, but could the memory leak be in the Mine object initializer ( -[Mine initWithMineName: latitudeInitial: longitudeInitial: commodity:] ) ??

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜