sqlite3 - stringWithUTF8String подтекает! - PullRequest
3 голосов
/ 05 июня 2010

Буду признателен, если кто-нибудь поможет мне решить мою проблему с утечкой. Утечки происходят в: aImage, aCategory, aDescription, категории и категории. Я освобождаю их в dealloc, но этого явно недостаточно:

-(void) readListFromDatabase:(char *) sqlStatement {
    // Setup some globals
    databaseName = @"mydatabase.sql";

    // Get the path to the documents directory and append the databaseName
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];

    // Setup the database object
    sqlite3 *database;

    // Init the categories Array
    categories = [[NSMutableArray alloc] init];

    // 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
        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
            // Loop through the results and add them to the feeds array
            while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                // Read the data from the result row
                aImage = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
                aCategory = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                aDescription = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];

                // Create a new category object with the data from the database             
                category=[[Category alloc] initWithName:aImage category_name:aCategory description_text:aDescription];

                // Add the category object to the categories Array
                [categories addObject:category];

                [category release];
            }
        }
        // Release the compiled statement from memory
        sqlite3_finalize(compiledStatement);
    }
    sqlite3_close(database);

}

- (void)dealloc {
    [databaseName release];
    [databasePath release];
    [categories release];
    [aImage release];
    [aCategory release];
    [aDescription release];
    [category release];


    [super dealloc];
}

Ответы [ 4 ]

2 голосов
/ 05 июня 2010

Если метод вызывается несколько раз, то строки будут утечки, потому что вам нужно освободить предыдущие значения. Вы также переусердствуете со строками в dealloc, потому что никогда не сохраняли их. Вы должны написать задания, как это:

[aImage release];
aImage = [[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)] retain];

Единственный другой способ утечки этих строк - это если вы вызываете этот метод из потока и не создали пул автоматического выпуска.

Если метод вызывается из нового потока, вам необходим пул автоматического выпуска:

- (void)myThreadFunction {
    NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
    try {
        // ...
        [self readListFromDatabase:whatever];
        // ...
    } @finally {
        [pool release];
    }

}
1 голос
/ 05 июня 2010

Этот метод, который вы опубликовали, вызывается более одного раза для одного и того же объекта? Если это так, категории из первого вызова будут вытекать, потому что он перезаписывается каждый раз, когда вызывается readListFromDatabase :. Попробуйте:

// Init the categories Array
[categories release];
categories = [[NSMutableArray alloc] init];
0 голосов
/ 19 ноября 2013

Немного поздно, но я обновлял старый проект и столкнулся с похожей проблемой. У меня был удобный метод, который был неправильно назван!

- (NSString *)initStringFromPosition:(int)index {
    char *str = (char *)sqlite3_column_text(init_statement, index);
    return (str) ? [NSString stringWithUTF8String:str] : @"";
}

Анализ сказал, что у меня утечка памяти, но просто переименуйте в

- (NSString *)stringFromPosition:(int)index {

решил проблему

0 голосов
/ 05 июня 2010

Почему приложение завершается, когда я включаю [aImage autorelease] в цикл (оно также завершается, если [aImage release])?

...