解决方案:在程序退出后释放内存。必须从磁盘读+写回到链接列表,然后重写以更新数据库!谢谢大家=)
你好,我基本上已经在这个数据库程序上工作了几个晚上,但我只是不断地达到死胡同。今天的作业到期了,如果你能帮我,我将不胜感激。=吨
数据库由一个链表实现,由几个文件组成:sdbm.c、sdbm.h、new.c、get.c、insert.c、put.c和remove.c。sdbm.c保存基于sdbm.h接口的数据库方法,其他文件包含使用sdbm中方法的主要方法。
第一个问题是insert程序,当我试图添加一个键和值对时,这个程序似乎工作得很好。。。也就是说,直到我们再次尝试调用insert程序。分配的内存似乎消失了!我一直在研究,试图找出为什么,即使我有错,为什么它消失后插入程序退出。下面是一些代码:
节点结构+全局变量:

struct dbase_Node {
  char *keyValue;
  char *element;
  struct dbase_Node *next;
};

typedef struct dbase_Node Node;

Node *head;

========
插入法
static bool sdbm_insert_back(Node **headRef, const char *key, const char *value)
{
  Node *new = (Node *)malloc(sizeof(Node));
  if (new == NULL)
    return false;
  else {
    new->keyValue = malloc(strlen(key));
    new->element = malloc(strlen(value));
    strcpy(new->keyValue, key);
    strcpy(new->element, value);

    new->next = *headRef;
    *headRef = new;
    return true;
  }
}

同步方法
bool sdbm_sync()
{
  if (!isOpen()) { return false; }

  if (fopen(databaseName, "w" ) == NULL) {
    error = SDBM_FOPEN_FAILED;
    return false;
  }

  Node *current = head;

  while (current != NULL) {
    fprintf(database, "Key: %s\n", current->keyValue);
    fprintf(database, "Value: %s\n", current->element);
    current = current->next;
  }
  return true;
}

我运行以下命令:
./新建[数据库]./insert[数据库][键][值]然后在我尝试插入更多节点之后,已经添加的节点已经消失。。。

最佳答案

new->keyValue = malloc(strlen(key));
new->element = malloc(strlen(value));
strcpy(new->keyValue, key);
strcpy(new->element, value);

这会导致一个off-by-one缓冲区溢出。
您需要为终止\0分配空间,因此请使用strlen(key) + 1strlen(value) + 1
或者更好,使用strdup()
new->keyValue = strdup(key);
new->element = strdup(value);

在程序存在之后,数据丢失的问题非常简单,但修复起来并不简单:您不是在内存中而是在任何地方存储它。当程序退出时,内存将自动释放。
所以你必须把它储存在一个文件里。

07-28 06:41