我刚写了一个简单的链表,但是当通过add()
和display()
遍历列表时,程序会出错。
#include <stdlib.h>
#include <stdio.h>
typedef struct entry {
void *value;
struct entry *next;
} entry;
typedef struct list {
entry *items;
} list;
list *create(void) {
list *l;
l = malloc (sizeof(list));
l->items = malloc(sizeof(entry*));
l->items->next = NULL;
return l;
}
void add(list *l, void *value) {
entry *temp, *last, *new;
for (temp = l->items; temp != NULL; temp = temp->next) {
last = temp;
}
new = malloc(sizeof(*new));
new->value = value;
new->next = NULL;
last->next = new;
}
void display(list *l) {
entry *temp;
for (temp = l->items; temp != NULL; temp = temp->next) {
printf("%s\n", temp->value);
}
}
int main(void) {
list *l = create();
add(l, "item1");
add(l, "item2");
add(l, "item3");
add(l, "item4");
display(l);
return 0;
}
我已经在一些机器上测试了代码,但是它可以在少数机器上运行而在其他机器上运行。我对错误的来源一无所知。
答案 0 :(得分:6)
这没有分配足够的空间:
l->items = malloc(sizeof(entry*));
它应该是sizeof(entry)
,或者如果您想要遵循您在其他地方使用的模式:
l->items = malloc(sizeof(*l->items));
结果,你现在正在践踏记忆。
答案 1 :(得分:3)
除了传递给FatalError提到的malloc
的错误大小外,您还为l->items
分配了内存
list *create(void) {
list *l;
l = malloc (sizeof(list));
l->items = malloc(sizeof(entry*));
l->items->next = NULL;
return l;
}
但是不要将l->items->value
设置为任何内容,因此它是一个未初始化的指针,当您尝试在打印时取消引用它
void display(list *l) {
entry *temp;
for (temp = l->items; temp != NULL; temp = temp->next) {
printf("%s\n", temp->value);
}
}
在循环的第一次迭代中,即使分配大小不足也不会导致一个段错误,很容易导致段错误。
答案 2 :(得分:2)
FatalError已经发现问题并发布了一个解决方案。我想补充说,比询问这样一个特定问题更好的方法是调试你的代码。
valgrind
是一个Linux工具,允许调试内存管理。您需要做的就是在应用程序中运行该工具,并查看其输出中的错误。
如果您使用“./myapp”运行应用程序,则只需运行:
# valgrind -v --leak-check=full --show-reachable=yes ./myapp
答案 3 :(得分:0)
要证明你不需要列表结构,因为它只带有一个“head”指针(我将原始条目重命名为llist,最后删除了列表和typedef):
#include <stdlib.h>
#include <stdio.h>
struct llist {
char *value;
struct llist *next;
};
void add(struct llist **ll, void *value) {
/* find the end of the list;
** keeping a pointer to the (final NULL) pointer.
** If this function is called with the first argument pointing to
** a NULL pointer (the empty list),
** this loop will iterate zero times.
*/
for ( ; *ll != NULL; ll = &(*ll)->next) {;}
*ll = malloc(sizeof(**ll));
(*ll)->value = value;
(*ll)->next = NULL;
}
void display(struct llist *l) {
for (; l != NULL; l = l->next) {
printf("%s\n", l->value);
}
}
int main(void) {
struct llist *l = NULL;
add(&l, "item1");
add(&l, "item2");
add(&l, "item3");
add(&l, "item4");
display(l);
return 0;
}