C object - sqlite3_open A memory leak, although sqlite3_close () applies

I get memory leaks in sqlite3_open, although sqlite_close, sqlite3_finalize apply, please direct me to where I am wrong. The project is in non-ARC.

-(BOOL)saveMedia:(NSDictionary *)details Download:(NSInteger)completed { //NSLog(@"media savemedia %@",[details objectForKey:@"type"]); BOOL saved = FALSE; NSInteger exists = [self findMedia:[details objectForKey:@"media_id"] playlist_id:[details objectForKey:@"playlist_id"] type:[details objectForKey:@"type"]]; sqlite3_stmt *statement; self.databasePath = [self getDBPath]; const char *dbpath = [databasePath UTF8String]; if (sqlite3_open(dbpath, &wazzupco) == SQLITE_OK) { const char *query_stmt; if (exists == 0) { query_stmt = "INSERT INTO media (media_id, title, description, file, views, thumbnail, version, playlist, playlist_id, author, created_at, type, playlist_created, timeout, playlist_order, media_order, playlist_promo_text, playlist_promo_url, playlist_promo_img,video_promo_text, video_promo_url, video_promo_img, dev_id, device_id, downloaded,slide_timeout) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; } else if([[details objectForKey:@"version"] integerValue] > exists) { NSString *querySQL = [NSString stringWithFormat:@"UPDATE %@ SET media_id=?, title=?, description=?, file=?, views=?, thumbnail=?, version=?, playlist=?, playlist_id=?, author=?, created_at=?, type=?, playlist_created=?, timeout=?, playlist_order=?, media_order=?, playlist_promo_text=?, playlist_promo_url=?, playlist_promo_img=?,video_promo_text=?, video_promo_url=?, video_promo_img=?, dev_id=?, device_id=?, downloaded=?, slide_timeout=? WHERE media_id='%@' AND playlist_id='%@' AND type='%@'", TABLE_MEDIA, [details objectForKey:@"media_id"], [details objectForKey:@"playlist_id"], [details objectForKey:@"type"]]; query_stmt = [querySQL UTF8String]; } else { //to make sure we won't update the database entry unless its a newer version return FALSE; } sqlite3_prepare_v2(wazzupco, query_stmt, -1, &statement, NULL); sqlite3_bind_text(statement, 1, [[details objectForKey:@"media_id"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 2, [[details objectForKey:@"title"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 3, [[details objectForKey:@"description"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 4, [[details objectForKey:@"file"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 5, [[details objectForKey:@"views"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 6, [[details objectForKey:@"thumbnail"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 7, [[details objectForKey:@"version"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 8, [[details objectForKey:@"playlist"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 9, [[details objectForKey:@"playlist_id"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 10, [[details objectForKey:@"author"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 11, [[details objectForKey:@"created_at"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 12, [[details objectForKey:@"type"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 13, [[details objectForKey:@"playlist_created"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 14, [[details objectForKey:@"timeout"] UTF8String], -1, NULL); sqlite3_bind_int(statement, 15, [[details objectForKey:@"playlist_order"] intValue]); sqlite3_bind_int(statement, 16, [[details objectForKey:@"media_order"] intValue]); sqlite3_bind_text(statement, 17, [[details objectForKey:@"playlist_promo_text"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 18, [[details objectForKey:@"playlist_promo_url"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 19, [[details objectForKey:@"playlist_promo_img"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 20, [[details objectForKey:@"video_promo_text"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 21, [[details objectForKey:@"video_promo_url"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 22, [[details objectForKey:@"video_promo_img"] UTF8String], -1, NULL); sqlite3_bind_int(statement, 23, [[details objectForKey:@"dev_id"] intValue]); sqlite3_bind_text(statement, 24, [[details objectForKey:@"device_id"] UTF8String], -1, NULL); sqlite3_bind_int(statement, 25, (int)completed); sqlite3_bind_text(statement, 26, [[details objectForKey:@"slide_timeout"] UTF8String], -1, NULL); if (sqlite3_step(statement) == SQLITE_DONE) { NSLog(@"media added. type:%@",[details objectForKey:@"type"]); saved = TRUE; } sqlite3_finalize(statement); //sqlite3_free(statement); //sqlite3_reset(statement); } sqlite3_close(wazzupco); if (completed != 0 && saved) { [self updateMediaStatus:[details objectForKey:@"file"] Download:1]; } return saved; } 

In the above code, I insert or update data from NSdictionary into the sqlite table, considering that the data already exists or not. The method runs fine, but it causes serious memory leaks (the method is called several times from the loop) when the tool indicates that the leak is in the if state (sqlite3_open (dbpath, & wazzupco) == SQLITE_OK).

Out tool

Leaked Object: Malloc 64Bytes

18

Address Size: 1.12KB Responsible library: libsqlite3.dylib Responsible frame: 0x34bdce30

+6
source share
2 answers

It seems that a memory leak in the above code occurs when the "else" script is executed.

 if (sqlite3_open(dbpath, &wazzupco) == SQLITE_OK) { const char *query_stmt; if (exists == 0) { query_stmt = "INSERT INTO media (media_id, title, description, file, views, thumbnail, version, playlist, playlist_id, author, created_at, type, playlist_created, timeout, playlist_order, media_order, playlist_promo_text, playlist_promo_url, playlist_promo_img,video_promo_text, video_promo_url, video_promo_img, dev_id, device_id, downloaded,slide_timeout) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; } else if([[details objectForKey:@"version"] integerValue] > exists) { NSString *querySQL = [NSString stringWithFormat:@"UPDATE %@ SET media_id=?, title=?, description=?, file=?, views=?, thumbnail=?, version=?, playlist=?, playlist_id=?, author=?, created_at=?, type=?, playlist_created=?, timeout=?, playlist_order=?, media_order=?, playlist_promo_text=?, playlist_promo_url=?, playlist_promo_img=?,video_promo_text=?, video_promo_url=?, video_promo_img=?, dev_id=?, device_id=?, downloaded=?, slide_timeout=? WHERE media_id='%@' AND playlist_id='%@' AND type='%@'", TABLE_MEDIA, [details objectForKey:@"media_id"], [details objectForKey:@"playlist_id"], [details objectForKey:@"type"]]; query_stmt = [querySQL UTF8String]; } else { //to make sure we won't update the database entry unless its a newer version return FALSE; } 

When another case is triggered, sqlite3_close () is not reached and will result in a memory leak in sqlite3_open

+4
source

Sorry, I am not familiar with these SQL Lite projects and without ARC. After some searches, I found this solution for You.I. You should consider converting your project to ARC. ARC will handle memory management for you. When ARC is turned on, the compiler inserts the appropriate memory management statements, such as save and release messages. It is best to use ARC because the compiler better understands the life cycle of an object and is less prone to human error.

to convert a project without ARC to ARC-compatible. This website can help you enable ARC.

+1
source

All Articles