C语言中双链表的分段错误
这让我快发疯了。当我在这个双链接列表上运行测试程序时,当我尝试释放列表时,它会给我一个分段错误。我知道由于没有正确释放分配的内存而导致内存泄漏,但无论我做什么尝试,它似乎都无法修复。任何关于我需要在哪里释放内存以避免内存泄漏和seg故障的帮助都将不胜感激C语言中双链表的分段错误,c,linked-list,C,Linked List,这让我快发疯了。当我在这个双链接列表上运行测试程序时,当我尝试释放列表时,它会给我一个分段错误。我知道由于没有正确释放分配的内存而导致内存泄漏,但无论我做什么尝试,它似乎都无法修复。任何关于我需要在哪里释放内存以避免内存泄漏和seg故障的帮助都将不胜感激 struct list { char *value; struct list *next; struct list *prev; }; const char *list_node_value(list_t *nod
struct list {
char *value;
struct list *next;
struct list *prev;
};
const char *list_node_value(list_t *node) {
return node->value;
}
list_t *list_first(list_t *list) {
return list;
}
list_t *list_last(list_t *list) {
return list->prev;
}
list_t *list_next(list_t *node) {
return node->next;
}
list_t *list_previous(list_t *node) {
return node->prev;
}
static void failed_allocation(void) {
fprintf(stderr, "Out of memory.\n");
abort();
}
static list_t *new_node(const char *value) {
list_t *node = malloc(sizeof(list_t));
if (!node) failed_allocation();
node->value = malloc(strlen(value));
if (!node->value) failed_allocation();
strcpy(node->value, value);
return node;
}
list_t *list_insert_before(list_t *list, list_t *node, const char *value) {
list_t *insert_node = new_node(value);
insert_node->prev = node->prev;
insert_node->next = node;
insert_node->next->prev = insert_node;
insert_node->prev->next = insert_node;
if (list == node) {
return insert_node;
} else {
return list;
}
}
list_t *list_append(list_t *list, const char *value) {
if (list) {
(void) list_insert_before(list, list, value);
return list;
} else {
list_t *node = new_node(value);
node->prev = node->next = node;
return node;
}
}
list_t *list_prepend(list_t *list, const char *value) {
if (list) {
return list_insert_before(list, list, value);
} else {
list_t *node = new_node(value);
node->prev = node->next = node;
return node;
}
}
list_t *list_remove(list_t *list, list_t *node) {
(node->prev)->next = node->next;
(node->next)->prev = node->prev;
if (list != node) {
return list;
} else {
return list->next == list ? NULL : list->next;
}
}
void list_free(list_t *list) {
while (list_remove(list, list_last(list)) != NULL) { }
}
void list_foreach(list_t *list, void (*function)(const char*)) {
if (list) {
list_t *cur = list_first(list);
do {
function(cur->value);
cur = cur->next;
} while (cur != list_first(list));
}
}
运行链接到或与的程序
这将告诉您内存丢失或指针取消引用的位置,等等。您的问题是堆损坏。 你有:
node->value = malloc(strlen(value));
应该是:
node->value = malloc(strlen(value)+1);
问题是您没有为'\0'
NUL字节分配空间。尝试:
if (!node) failed_allocation();
node->value = malloc(strlen(value)+1);
我在这里看到了至少一个缺陷:
node->value = malloc(strlen(value));
保持零终止符字符应为strlen(value)+1
,否则下一次strcpy()
调用将导致缓冲区溢出并可能损坏堆:
node->value = malloc(strlen(value) + 1);
你比我快了几秒钟。对不起,我没问这个问题。:)@小毛:对不起,我错过了这个:)为什么在释放列表时会出现问题?如前所述,我可以看到这会导致内存问题,但我如何释放列表?如果我在list_remove函数中放入一个空闲(节点),我只会得到一个segfault@user1691282您将
free()
调用放在了什么位置,然后是什么导致seg故障<代码>自由()调用ifself?在释放被删除的节点之前,您应该从中读取数据。@ScottHunter如果缓冲区溢出会损坏该节点,它可能会导致free()
出现问题heap@Rost我把free()放在这样的位置:list\t*list\u remove(list\t*list,list\t*node){(node->prev)->next=node->next;(node->next)->prev=node->prev;如果(list!=node){free(node);return list;}else{return list->next==list?NULL:list->next;}但是我仍然没有释放所有内存,我不知道如何修复它
node->value = malloc(strlen(value) + 1);