HJY bio photo

HJY

A Code Lover. Also good at cooking

Github
I had an interesting bug today, when I used SQlite C interface. Take a look at the following code: [code lang="c"] char *query[100]; sprintf(query, "SELECT PROFILE FROM profileTable WHERE ID=%i", id); sqlite3 *DB = sqlite3_open(....); sqlite3_stmt *statement; char *profile = nil; if (sqlite3_prepare_v2(DB, query,-1, &statement, nil) == SQLITE_OK) { while (sqlite3_step(statement) == SQLITE_ROW) { profile = (char *)sqlite3_column_text(statement, 0); } } sqlite3_finalize(statement); sqlite3_close(profileDB); if(profile==nil) { sqlite3_close(profileDB); return; } else if(strlen(profile)<=0) { sqlite3_close(profileDB); return; } //some further operation on the string //operations... //operations... [/code] It crashed on strlen(profile)=0 for EXE_BAD_ACCESS. It took me about two hours to find that it was something wrong with sqlite. How I fixed it? Just move sqlite3_close down as: [code lang="c"] //Omission. The same as above sqlite3_finalize(statement); //sqlite3_close(profileDB); move it after operation code!! if(profile==nil) { sqlite3_close(profileDB); return; } else if(strlen(profile)<=0) { sqlite3_close(profileDB); return; } //some further operation on the string //operations... //operations... //close sqlite DB when all calculation is done sqlite3_close(profileDB); [/code] Reason: sqlite3_close frees all memory of the sqlite DB and makes "profile" points to a illegal address. Then strlen will try to access a illegal address and get the signal.