2012-08-02 69 views
4

我使用SQLCipher来存储加密的SQLite数据库。但是,当我使用sqlite3_key加密数据库时,我开始发生内存泄漏。遵守以下样品:SQLite是否会使用SQLCipher扩展泄漏内存?

#include <sqlite3.h>  

int main() 
{ 
    sqlite3 * connection; 
    sqlite3_open_v2(":memory:", &connection, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); 
    sqlite3_key(connection, "passphrase", 10); 
    sqlite3_close(connection); 
} 

此示例产生了内存泄漏。如果我删除对sqlite3_key的呼叫,则内存泄漏消失。

我已经缩小了一些可能的元凶:

  • 尽管样本使用基于文件的数据库时使用的内存数据库(因此":memory:"),我看到了同样的结果。
  • 来自sqlite3_*调用的所有返回码都是SQLITE_OK,表示没有任何错误。
  • 缓冲区长度为10"passphrase"不是问题所在。

但是,无论我创建多少个连接或使用多少个不同的加密密钥,内存泄漏总是大约8千字节。这让我怀疑这实际上不是内存泄漏,而是SQLite/SQLCipher中的一些常量全局内存不能手动释放。

有没有人遇到过这个?有没有办法摆脱泄漏?即使这不是官方的内存泄漏,也很难用这个礼物来检测真正的内存泄漏。我正在使用SQLCipher library for Windows

+0

你是如何检测内存泄漏的? _CrtDumpMemoryLeaks()? – 2012-08-02 19:59:33

+0

是的,在Boost单元测试框架内。 – 2012-08-02 20:02:13

+0

在运行最新的repo代码的Linux上,上述代码没有问题。 – netcoder 2012-08-02 20:16:30

回答

2

我已经研究了这一点,并且这些报告的泄漏是由OpenSSL分配的内存的结果。由于SQLCipher不知道应用程序严格使用它的时间,因此EVP_cleanup()未被调用,并且valgrind将内存报告为泄漏。我们正在努力寻找一种简单的修复方法,它将尝试通过一些简单的引用计数来识别SQLCipher不再使用OpenSSL结构,因此可以自动调用EVP_cleanup()

作为在下一版SQLCipher之前的快速解决方法,您可以在退出之前在程序中手动调用EVP_cleanup()