首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过空指针传递的GDBM对象丢失/损坏

通过空指针传递的GDBM对象丢失/损坏
EN

Stack Overflow用户
提问于 2013-07-01 06:15:27
回答 1查看 122关注 0票数 1

我有一个程序,可以使用GDBM或京都内阁作为DBM库。我已经编写了一些函数来抽象两者之间的差异,并传递空指针来代替数据库文件(在GDBM的情况下是GDBM_FILE,在Kyoto的情况下是KCDB * )。KC的一切工作正常,但是当我尝试使用GDBM后端时,数据库不知何故在将其传递给不同的函数时“迷失”了。当我尝试强制转换指针并取消对它的引用,然后将其传递给GDBM函数之一时,它会出现分段错误,并且在调试器中它会报告db文件不存在。

下面是一些可以重现这个问题的代码:

代码语言:javascript
复制
#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存储到一个整数时,它突然就能工作了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-01 06:28:43

你的问题是获取从gdbm_open返回的指针的地址,而不是它的值。令人困惑的部分来自GDBM_FILE的定义-它是一个指向结构的指针:

代码语言:javascript
复制
typedef struct {int dummy[10];} *GDBM_FILE;

你得到它的地址,也就是指针的位置,而不是指针值:

代码语言:javascript
复制
void *db = &database;

可以通过将转换行替换为以下内容来解决此问题:

代码语言:javascript
复制
void *db = (void *)database;

代码语言:javascript
复制
GDBM_FILE database = (GDBM_FILE)db;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17395358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档