解决方案:在程序退出后释放内存。必须从磁盘读+写回到链接列表,然后重写以更新数据库!谢谢大家=)
你好,我基本上已经在这个数据库程序上工作了几个晚上,但我只是不断地达到死胡同。今天的作业到期了,如果你能帮我,我将不胜感激。=吨
数据库由一个链表实现,由几个文件组成: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) + 1
和strlen(value) + 1
。或者更好,使用
strdup()
:new->keyValue = strdup(key);
new->element = strdup(value);
在程序存在之后,数据丢失的问题非常简单,但修复起来并不简单:您不是在内存中而是在任何地方存储它。当程序退出时,内存将自动释放。
所以你必须把它储存在一个文件里。