我在调用DB-> put()后释放内存有问题。 当我这样做时,它会说“双重免费或腐败”。
代码示例:
DBT key,value;
int err;
...
memset(value,0,sizeof(DBT));
value.data=malloc(10);
memset(value.data,10);
value.flags=DB_DBT_MALLOC;
...
value.size=10;
...
if((err=db->put(db,NULL,&key,&value,0))){
...
}
free(value.data);
C API参考不包含有关该主题的任何信息,它仅提供有关在检索(但不存储)数据时使用DB_DBT_MALLOC的一些信息:
设置此标志后,Berkeley DB将为返回的键或数据项(使用malloc(3)或用户指定的malloc函数)分配内存,并在键的数据字段中返回指向它的指针或数据DBT结构。因为任何分配的内存成为调用应用程序的责任,调用者必须确定是否使用数据字段的返回值分配内存。
当调用DB-> put时,Berkeley DB不会返回任何数据,它只存储一个键/数据对。是否复制数据,或者在调用DB-> close或ENV->关闭之前存储器是否应该存在?
答案 0 :(得分:1)
DB_DBT_MALLOC
对db->put()
无效,因为db->put()
会复制数据。所以你最有可能在其他地方破坏你的堆。这种错误并不总是表现在它们造成的地方。我的猜测是你正在写一些缓冲区的结尾。尝试在其上运行Valgrind,跟踪这类问题通常非常有用。
我运行了这个简单的测试程序,它运行得很好,valgrind报告没有泄漏:
void test() {
DB *DB;
DBT key;
DBT data;
DBT value;
int i;
db_create(&DB, NULL, 0);
if(DB->open(DB, NULL, "tmp.db2", NULL, DB_BTREE, DB_CREATE, 0664) != 0) {
printf("DB->open failed!\n");
exit(0);
}
memset(&value,0,sizeof(value));
value.size=10;
value.data=malloc(value.size);
memset(&key,0,sizeof(key));
key.data=malloc(sizeof(unsigned int));
key.size = sizeof(unsigned int);
for(i=0; i < 10; i++) {
*(unsigned int*)key.data = i;
memset(value.data, 0, value.size); /* valgrind complains if I leave this out? */
sprintf(value.data, "test %d", i);
if(DB->put(DB, NULL, &key, &value, 0 ) != 0) {
printf("key stored failed\n");
exit(-1);
}
}
free(value.data);
free(key.data);
key.data = malloc(sizeof(unsigned int));
key.size = sizeof(unsigned int);
*(unsigned int*)key.data=5;
memset(&data,0,sizeof(data));
data.flags = DB_DBT_MALLOC;
DB->get(DB, NULL, &key,&data, 0);
printf("size: %d data: %s\n", data.size, (const char*)data.data);
DB->close(DB, 0);
free(data.data);
free(key.data);
return;
}