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;
}

现在好像没有泄漏了