Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调用DB->;后是否应取消分配数据;在数据上放置DB_DBT_MALLOC标志?_C_Memory Management_Berkeley Db - Fatal编程技术网

调用DB->;后是否应取消分配数据;在数据上放置DB_DBT_MALLOC标志?

调用DB->;后是否应取消分配数据;在数据上放置DB_DBT_MALLOC标志?,c,memory-management,berkeley-db,C,Memory Management,Berkeley Db,调用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

调用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->close之前内存是否有效?

DB\u DBT\u 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;
}
void测试(){
分贝*分贝;
DBT键;
DBT数据;
DBT值;
int i;
db_create(&db,NULL,0);
如果(DB->open(DB,NULL,“tmp.db2”,NULL,DB_BTREE,DB_CREATE,0664)!=0){
printf(“数据库->打开失败!\n”);
出口(0);
}
memset(&value,0,sizeof(value));
值。大小=10;
value.data=malloc(value.size);
memset(&key,0,sizeof(key));
key.data=malloc(sizeof(unsigned int));
key.size=sizeof(无符号整数);
对于(i=0;i<10;i++){
*(无符号int*)key.data=i;
memset(value.data,0,value.size);/*valgrind会抱怨我是否忽略了这个*/
sprintf(value.data,“测试%d”,i);
if(DB->put(DB,NULL,&键,&值,0)!=0){
printf(“密钥存储失败\n”);
出口(-1);
}
}
免费(价值数据);
免费(密钥数据);
key.data=malloc(sizeof(unsigned int));
key.size=sizeof(无符号整数);
*(无符号int*)键。数据=5;
memset(&data,0,sizeof(data));
data.flags=DB_DBT_MALLOC;
DB->get(DB,NULL,&key,&data,0);
printf(“大小:%d数据:%s\n”,data.size,(const char*)data.data);
DB->关闭(DB,0);
免费(数据、数据);
免费(密钥数据);
返回;
}

您能提供一个代码示例(越小越好)来演示此问题吗?@simonc code sample已添加。对不起,我无法说明错误是什么。不过有一些事情你可以调查一下。。。键和值的许多字段未初始化;这些字段中的大多数似乎都有一些重要意义。您可以尝试初始化所有值字段以及建议与键相关的字段。您还可以检查db->put()返回的错误,看看是否有任何关于错误的提示。@simonrc这是我实际做的,我已经编辑了代码片段来显示它。