I believe the following quick start example contains a possible memory leak. This is the program found at the following link:
http://www.sqlite.org/quickstart.html The error can be reproduced by compiling the example and running it for the following SQL statement: ./a.out tmptable "drop table junk" Since the table "junk" does not exist, zErrMsg is first allocated memory (legacy.c:129) in the statement below: /src/legacy.c (line 129) if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){ *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db))); However, it appears that this memory is not freed. Not even in sqlite3_close(db). Shown below the valgrind statement and the report. valgrind --logfile=valgrind.output --leak-check=yes --tool=memcheck ./a.out tmptable "drop table junk" ==31665== LEAK SUMMARY: ==31665== definitely lost: 20 bytes in 1 blocks. ==31665== possibly lost: 0 bytes in 0 blocks. ==31665== still reachable: 128 bytes in 2 blocks. ==31665== suppressed: 0 bytes in 0 blocks. ==31665== Reachable blocks (those to which a pointer was found) are not shown. ==31665== To see them, rerun with: --show-reachable=yes FIX: rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg); if( rc!=SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); /* This will free zErrMsg if assigned */ if (zErrMsg) free(zErrMsg); } After making the following change, valgrind reports no memory leaks. Why It My Be Relevant: Some SQL commands seemed to be ignored by design. For example, SQLite can indirectly support the "DROP TABLE IF EXIST junk" by executing the "drop table junk" and ignoring the error. However, when there are many such statements, with long running programs, the memory is never freed. At least I believe it is not. If the above is correct, changing the example my help users. Regards, Mike Chirico #include <stdio.h> #include <sqlite3.h> static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } int main(int argc, char **argv){ sqlite3 *db; char *zErrMsg = 0; int rc; if( argc!=3 ){ fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]); exit(1); } rc = sqlite3_open(argv[1], &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg); if( rc!=SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); /* Problem above zErrMsg is } sqlite3_close(db); return 0; }