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



所以我目前正在通过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: %snThe data is: %sn", (char *)key.data, (char *)data.data);
}

谁能告诉我我需要补充什么吗?我已经检查了包含Berkeley DB所有信息的sourceforge页面,据我所知,我只需要添加DB->set_flags行就可以允许重复条目,但可能有我遗漏的东西吗?

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

具体地,db_createset_flagsopencursor返回错误指示。

如果像您在注释中指出的那样,是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 %pn", rc, DBpointer);
fflush (stdio); // and possibly also: fsync (fileno (stdio));

这将是一个良好的开端。

最好是一路使用类似的东西

#define CHKERR(x) if(rc!=0){printf("%s err=%dn",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: %snThe data is: %sn", (char *)key.data, (char *)data.data);
}

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

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

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

最新更新