我有一个程序,可以使用GDBM或京都内阁作为DBM库。我已经编写了一些函数来抽象两者之间的差异,并传递空指针来代替数据库文件(在GDBM的情况下是GDBM_FILE,在Kyoto的情况下是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()时出现"file not found“错误。正如注释所指出的,如果我没有显式地存储指向int的另一个空指针,那么程序就会运行得很好。
在我的实际程序中,当我调用gdbm_store()时,它会“丢失”,并且它是我唯一使用的空指针(在这个测试程序中,foo指针只是为了检查是否正常)。
我敢肯定,在C中内存分配的变幻莫测中,有一些东西是我忘记或不理解的。为什么引用GDBM数据库的空指针会丢失/损坏,而引用int的空指针却没有呢?为什么,当我不尝试将解引用的空指针foo存储到一个整数时,它突然就能工作了?
发布于 2013-07-01 06:28:43
你的问题是获取从gdbm_open返回的指针的地址,而不是它的值。令人困惑的部分来自GDBM_FILE的定义-它是一个指向结构的指针:
typedef struct {int dummy[10];} *GDBM_FILE;你得到它的地址,也就是指针的位置,而不是指针值:
void *db = &database;可以通过将转换行替换为以下内容来解决此问题:
void *db = (void *)database;和
GDBM_FILE database = (GDBM_FILE)db;https://stackoverflow.com/questions/17395358
复制相似问题