c - 伯克利数据库 - 重复条目段错误

标签 c database segmentation-fault berkeley-db

所以我目前正在通过 C 开发 Berkeley 数据库,我遇到了一个关于允许重复数据的小问题。如果我不允许通过 DB->set_flags 重复条目,并且我使用游标遍历数据库中的项目,那么一切正常。当我在我的程序中添加 DB->set_flags 行并且不做任何更改时,我遇到了段错误并且我不知道如何修复它,考虑到它在没有重复条目的情况下工作得很好。代码如下:

DB *dates_db;
db_create(&dates_db, NULL, 0);
dates_db->set_flags(dates_db, DB_DUP);
dates_db->open(dates_db, NULL, "da.idx", NULL, DB_BTREE, 0, 0664);

DBT key, data;
memset(&key, 0, sizeof(key)); 
memset(&data, 0, sizeof(data));

DBC *DBpointer;
dates_db->cursor(dates_db, NULL, &DBpointer, 0);

while(DBpointer->c_get(DBpointer, &key, &data, DB_NEXT) != DB_NOTFOUND)
{
    printf("The key is: %s\nThe data is: %s\n", (char *)key.data, (char *)data.data);
}

任何人都可以告诉我我需要添加什么吗?我检查了包含有关 Berkeley DB 的所有信息的 sourceforge 页面,据我所知,我只需要添加 DB->set_flags 行以允许重复条目,但我是否遗漏了什么?

最佳答案

首先,您应该始终在函数失败时检查返回值。

具体来说,db_createset_flagsopencursor all 返回一个错误提示。

如果正如您在评论中指出的那样,是 c_get 导致了 SIGSEGV,您可能需要确保游标确实已正确创建。

改变:

DBC *DBpointer;
dates_db->cursor(dates_db, NULL, &DBpointer, 0);

到:

DBC *DBpointer = (DBC*)0xdeadbeef;
int rc = dates_db->cursor(dates_db, NULL, &DBpointer, 0);
printf ("DEBUG: %d %p\n", rc, DBpointer);
fflush (stdio); // and possibly also: fsync (fileno (stdio));

将是一个好的开始。

更好的办法是一路走下去并使用类似的东西:

#define CHKERR(x) if(rc!=0){printf("%s err=%d\n",x,rc);fflush(stdout);exit(1);}
int rc;
DB *dates_db;

rc = db_create(&dates_db, NULL, 0);
CHKERR("create");

rc = dates_db->set_flags(dates_db, DB_DUP);
CHKERR("set_flags");

rc = dates_db->open(dates_db, NULL, "da.idx", NULL, DB_BTREE, 0, 0664);
CHKERR("open");

DBT key, data;
memset(&key, 0, sizeof(key)); 
memset(&data, 0, sizeof(data));

DBC *DBpointer;
rc = dates_db->cursor(dates_db, NULL, &DBpointer, 0);
CHKERR("cursor");

while((rc = DBpointer->c_get(DBpointer, &key, &data, DB_NEXT)) != DB_NOTFOUND)
{
    CHKERR("c_get");
    printf("The key is: %s\nThe data is: %s\n", (char *)key.data, (char *)data.data);
}

根据进一步的评论,您在 open 调用中收到错误 22,这是 EINVAL(至少在我的系统上),这意味着您的一个参数不正确。

根据网络搜索,open 调用似乎有一些变体,参数范围在 5 到 7 个之间。一些Oracle BDB doco指出它需要 五个 参数(没有数据库指针,也没有事务指针)但同一文档中的示例代码(和 other Oracle doco )具有您的七个参数形式。

查看您的 BDB 头文件以了解您应该使用哪一个可能是值得的。

关于c - 伯克利数据库 - 重复条目段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10022540/

相关文章:

在 C 中不使用 main() 编译和运行程序

c - SQLite 3 语句准备段错误

c++ - 类定义中的段错误无法找出位置

c - 获取圆内的 x,y

c - WinAPI 使用 SetfilePointer 测试 EOF

php - 将信息数组传递到数据库中

database - 创建了用户,那么现在谁拥有创建的表?

C:从带有链表和哈希表的txt文件实现的字典无法找到文件中存在的单词

c - 在 Linux 上,当使用 C 执行与端口 0(选择一个随机端口)的套接字绑定(bind)时,我得到 errno 98,Address already in use。这怎么可能?

c# - 如何像很多游戏一样快速发送信息?