Reputation: 381
I've coded 2 simple functions.
The first one establishes connection with my database and enable foreign key support:
int hmd_db_connect (sqlite3 *db) {
char *sql;
sqlite3_stmt *stmt;
if (sqlite3_open_v2(HMD_DB_PATH, &db,
SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_SHAREDCACHE,
NULL) != SQLITE_OK) {
hmd_log_err("Failed to connect to database [Path: %s]: %s.",
HMD_DB_PATH, sqlite3_errmsg(db));
return -1;
}
sql = hmd_make_str("PRAGMA foreign_keys = ON");
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL) != SQLITE_OK) {
hmd_log_err("Failed to prepare SQL [%s]: %s.",
sql, sqlite3_errmsg(db));
hmd_db_disconnect(db);
free(sql);
return -1;
}
if (sqlite3_step(stmt) != SQLITE_DONE) {
hmd_log_err("Failed to enable foreign key support: %s.",
sqlite3_errmsg(db));
sqlite3_finalize(stmt);
hmd_db_disconnect(db);
free(sql);
return -1;
}
sqlite3_finalize(stmt);
free(sql);
return 0;
}
The second closes the connection:
int hmd_db_disconnect (sqlite3 *db) {
if (sqlite3_close(db) != SQLITE_OK) {
hmd_log_err("Failed to disconnect from database [Path: %s]: %s.",
HMD_DB_PATH, sqlite3_errmsg(db));
return -1;
}
return 0;
}
Then in my main
function, I call these 2 functions:
_info("Connecting to database.\n");
hmd_db_connect(db);
_info("Database connected.\n");
_info("Disconnecting from database.\n");
hmd_db_disconnect(db);
_info("Database disconnected.\n");
The program doesn't show any error message. But when I run it with valgrind
, it shows possible memory leak:
==11079== LEAK SUMMARY:
==11079== definitely lost: 0 bytes in 0 blocks
==11079== indirectly lost: 0 bytes in 0 blocks
==11079== possibly lost: 57,768 bytes in 47 blocks
==11079== still reachable: 0 bytes in 0 blocks
==11079== suppressed: 0 bytes in 0 blocks
==11079==
==11079== For counts of detected and suppressed errors, rerun with: -v
==11079== ERROR SUMMARY: 47 errors from 47 contexts (suppressed: 6 from 6)
I've checked the log of valgrind
, all of the errors are detected inside the shared library of sqlite3, and I don't see any unfree'd variable.
Any idea please ?
Upvotes: 0
Views: 2241
Reputation: 1286
I think hmd_db_connect
is incorrect. It should return sqlite3*
, but it takes sqlite3*
instead of sqlite3**
. You just lose sqlite3*
returned by sqlite3_open_v2
, imagine:
sqlite3* db = NULL;
hmd_db_connect(db);
db
still will be NULL even if hmd_db_connect
successfully opened the database.
I've modified the code:
int hmd_db_connect(sqlite3 **db) {
char *sql;
sqlite3_stmt *stmt;
if (sqlite3_open_v2(HMD_DB_PATH, db,
SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_SHAREDCACHE,
NULL) != SQLITE_OK) {
hmd_log_err("Failed to connect to database [Path: %s]: %s.",
HMD_DB_PATH, sqlite3_errmsg(*db));
return -1;
}
sql = hmd_make_str("PRAGMA foreign_keys = ON");
if (sqlite3_prepare_v2(*db, sql, strlen(sql), &stmt, NULL) != SQLITE_OK) {
hmd_log_err("Failed to prepare SQL [%s]: %s.",
sql, sqlite3_errmsg(*db));
hmd_db_disconnect(*db);
free(sql);
return -1;
}
if (sqlite3_step(stmt) != SQLITE_DONE) {
hmd_log_err("Failed to enable foreign key support: %s.",
sqlite3_errmsg(*db));
sqlite3_finalize(stmt);
hmd_db_disconnect(*db);
free(sql);
return -1;
}
sqlite3_finalize(stmt);
free(sql);
return 0;
}
and it seems no leaks now.
Upvotes: 2