C 中的 Malloc 问题
解决方案:分配的内存在程序退出后被释放。必须从磁盘读+写回链表,然后重写以更新数据库!谢谢大家 =)
你好,过去几个晚上我基本上一直在研究这个数据库程序,但我只是不断进入死胡同。作业今天到期,所以如果您能帮助我,我将不胜感激。 =T
数据库是用链表实现的,由几个文件组成:sdbm.c、sdbm.h、new.c、get.c、insert.c、put.c 和remove.c。 sdbm.c 保存基于 sdbm.h 接口的数据库方法,其他文件包含使用 sdbm 方法的主要方法。
第一个问题与插入程序有关,当我尝试添加键和值对时,它似乎工作正常......也就是说,直到我们再次尝试调用插入程序。分配的内存好像消失了!我一直在研究,试图找出为什么即使我已经分配了内存,为什么它在插入程序退出后会消失。这里是一些代码:
- 节点结构+全局变量:
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;
}
我运行以下
: ./new [database] <-- 工作正常 ./insert [database] [key] [value] <--似乎工作正常
然后在我尝试插入更多之后,已经添加的节点消失了......
Solution: Allocated memory is freed up after a program exits. Have to read+write from disk back into a linked list, and then rewrite to update the database! Thank you everyone =)
Hello, I've basically been working on this database program for the past few nights but I just continuously reach dead ends. The assignment is due today so if you could help me out, it would be very much appreciated. =T
The database is implemented with a Linked List and consists of a few files: sdbm.c, sdbm.h, new.c, get.c, insert.c, put.c, and remove.c. sdbm.c holds the methods for the database based on the sdbm.h interface, and the other files contain main methods that use the methods from sdbm.
The first problem comes with the insert program, which seems to work fine when I try to add in a key and value pair ... that is, until we try to call the insert program again. The memory allocated seems to have disappeared! I've been researching, trying to figure out why even though I have malloced, why does it disappear after the insert program exits. Here is some code:
- The node structure + global variable:
struct dbase_Node {
char *keyValue;
char *element;
struct dbase_Node *next;
};
typedef struct dbase_Node Node;
Node *head;
========
- The insert method
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;
}
}
- The sync method
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;
}
I run the following:
./new [database] <-- works fine
./insert [database] [key] [value] <--seems to work fine
And then after I try to insert more, the already added nodes have disappeared ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这会导致差一缓冲区溢出。
您需要为终止
\0
分配空间,因此请使用strlen(key) + 1
和strlen(value) + 1
。或者甚至更好,使用strdup():
程序存在后数据丢失的问题非常简单,但修复起来并不容易:除了内存中之外,您没有将其存储在任何地方。当程序退出时,内存会自动释放。
因此,您必须将其存储在文件中。
This causes an off-by-one buffer overflow.
You need to allocate space for the terminating
\0
, so usestrlen(key) + 1
andstrlen(value) + 1
.Or even better, use
strdup()
:The problem of your data being lost after the program exists is very simple but not simple to fix: You are not storing it anywhere but in memory. And memory is automatically free'd when the program exits.
So you'll have to store it e.g. in a file.
你的问题中的这一行:
意味着您运行程序一次来创建数据库,然后再次创建密钥/值对。您是否在任何地方将数据保存到磁盘?
This line in your question:
implies you are running the program once to create a database, then again to create the key/value pairs. Are you anywhere persisting your data to disk?
我读得对吗?对于每一项操作,您都要启动一个新流程吗?如果是这样,那就有问题了:一旦进程终止,它分配的所有内存都会被释放。
您需要的是持久存储。在通常的操作系统中,进程内存不是持久的(有一些操作系统,分配的内存是持久的,但仍然绑定到某个进程,所以即使在这样的操作系统中,这种程序也无法工作)。
Do I read that right? For each of those operations you're starting a new process? If so there's your problem: Once a process terminates all the memory it allocated is freed.
What you need is persistent storage. In the usual operating systems process memory is not persistent (there are some OS in which allocated memory is persistent, but still bound to a certain process, so even in such a OS this kind of program won't work).
我觉得问题出在 else 部分,你需要检查它是否是列表中的第一个节点,如果是的话分配内存,存储到 head 中。下次你调用它时,如果列表不为空,则链接 head->next 到你新创建的列表。
I feel the issue is in the else part, u need to check if it's the first node in the List if so allocate memory, store into head. Next time u call it if the list is not null then link head->next to ur newly created one.
建议:在
sdbm_sync
中写入数据后关闭文件。另外,在
sdbm_sync
中,database
定义在哪里? fopen 行是否缺少某些内容? ???Suggestion: in
sdbm_sync
close the file after writing the data.Also in
sdbm_sync
where isdatabase
defined? Is the fopen line missing somthing? ???