Sqlite3 - stringWithUTF8String is leaking!

I would appreciate if someone would help me solve my problem. Leaks occur at: aImage, aCategory, aDescription, category and categories. I release them in dealloc, but obviously this is not enough:

-(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];
}
+3
source share
4 answers

If the method is called multiple times, the lines will flow because you need to release the previous values. You also inflate lines in dealloc because you never saved them. You should write the assignments as follows:

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

The only way these lines can flow is that you call this method from the stream and you have not created an automatic publishing pool.

, :

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

}
+2

, , ? , , , readListFromDatabase:. :

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

, [aImage autorelease] ( , [aImage release])?

0

, . , !

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

, ,

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

0

Source: https://habr.com/ru/post/1748639/


All Articles