【发布时间】:2013-06-28 00:52:14
【问题描述】:
我有一个程序可以将 GDBM 或 Kyoto Cabinet 用作 DBM 库。我编写了一些函数来抽象出两者之间的差异,并且我传递了 void 指针来代替数据库文件(在 GDBM 的情况下为GDBM_FILE,在京都内阁的情况下为KCDB *)。 KC 的一切工作正常,但是当我尝试使用 GDBM 后端时,数据库在将它传递给不同的函数时会以某种方式“丢失”。当我尝试强制转换指针并取消引用它,然后将其传递给其中一个 GDBM 函数时,它会出现段错误,并且在调试器中它会抱怨 db 文件不存在。
这里有一些可以重现问题的代码:
#include <gdbm.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
void *
dbopen (void)
{
printf ("opening\n");
GDBM_FILE database = gdbm_open ("test.db", 512, GDBM_WRCREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, NULL);
if (!database)
{
printf ("cannot open database\n");
return NULL;
}
void *db = &database;
return db;
}
void
dbclose (void *db, void *foo)
{
printf ("%d\n", *(int *)foo);
GDBM_FILE database = *(GDBM_FILE *)db;
if (!database)
{
printf ("database lost\n");
return;
}
printf ("closing\n");
gdbm_close (database);
return;
}
void
fun (void *db, void *foo)
{
GDBM_FILE database = *(GDBM_FILE *)db;
datum key, value;
int bar = *(int *)foo; /* and yet, if I remove this line and the next */
printf ("%d\n", bar); /* one, it works! */
printf ("%d\n", *(int *)foo);
if (!database)
printf ("no db?\n");
key.dptr = "baz";
key.dsize = 4;
value.dptr = "quux";
value.dsize = 4;
printf ("storing\n");
gdbm_store (database, key, value, GDBM_REPLACE);
printf ("all done\n");
return;
}
int
main (void)
{
int foo = 5;
void *dbp = dbopen ();
void *foop = &foo;
fun (dbp, foop);
dbclose (dbp, foop);
}
当我运行该代码时,它在调用gdbm_close() 时出现“找不到文件”错误。正如 cmets 所指出的,如果我没有明确地将另一个 void 指针存储到一个 int,那么程序运行得很好。
在我的实际程序中,当我调用 gdbm_store() 时它会“丢失”,这是我正在使用的唯一 void 指针(在这个测试程序中,foo 指针应该只是一个健全性检查) .
我确信在 C 中的内存分配变幻莫测中有些东西我忘记了或不理解。当引用 int 的 void 指针没有时,为什么引用 GDBM 数据库的 void 指针会丢失/损坏?为什么,当我不尝试将取消引用的 void 指针 foo 存储到 int 时,它会突然起作用吗?
【问题讨论】:
标签: c void-pointers gdbm