sqlite3的共享库中可能存在内存泄漏
Possible memory leak in the shared library of sqlite3
我编写了 2 个简单的函数。
第一个与我的数据库建立连接并启用外键支持:
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;
}
第二个关闭连接:
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;
}
然后在我的 main
函数中,我调用了这两个函数:
_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");
程序没有显示任何错误信息。但是当我 运行 它与 valgrind
时,它显示可能的内存泄漏:
==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)
我查看了valgrind
的日志,所有错误都在sqlite3的共享库中检测到,我没有看到任何未释放的变量。
有什么想法吗?
我认为 hmd_db_connect
不正确。它应该 return sqlite3*
,但它需要 sqlite3*
而不是 sqlite3**
。你只是失去了 sqlite3*
returned by sqlite3_open_v2
,想象一下:
sqlite3* db = NULL;
hmd_db_connect(db);
即使hmd_db_connect
成功打开数据库,db
仍然是NULL。
我修改了代码:
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;
}
现在好像没有泄漏了
我编写了 2 个简单的函数。
第一个与我的数据库建立连接并启用外键支持:
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;
}
第二个关闭连接:
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;
}
然后在我的 main
函数中,我调用了这两个函数:
_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");
程序没有显示任何错误信息。但是当我 运行 它与 valgrind
时,它显示可能的内存泄漏:
==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)
我查看了valgrind
的日志,所有错误都在sqlite3的共享库中检测到,我没有看到任何未释放的变量。
有什么想法吗?
我认为 hmd_db_connect
不正确。它应该 return sqlite3*
,但它需要 sqlite3*
而不是 sqlite3**
。你只是失去了 sqlite3*
returned by sqlite3_open_v2
,想象一下:
sqlite3* db = NULL;
hmd_db_connect(db);
即使hmd_db_connect
成功打开数据库,db
仍然是NULL。
我修改了代码:
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;
}
现在好像没有泄漏了