C语言 在双重链表实现中存在分割错误的问题



我对C很陌生,我不知道为什么我从这个代码中得到分段错误:

void delete_list(LIST *list)
{
NODE* n = list->head;
while(n != list->tail)
{
NODE* next = n->next;
free(n);
n = next;
}
free(n);
free(list);
}

我很确定这是我的代码的一部分,有错误,但如果不是我可以张贴我的代码的其余部分。NODE和LIST都是使用malloc()创建的。该代码是双链表的基本框架。

编辑2:这是复制我正在做的代码。非常基本的测试用例,但是失败了。首先是头文件list.h,然后是主文件list.c。我还删除了第一个编辑,以便稍微清理一下这个问题。
#ifndef __LIST_H__
#define __LIST_H__
typedef struct node {
char *value;  /* Pointer to the string we are storing. */
struct node *previous;  /* Pointer to the preceding node in the list. */
struct node *next;  /* Pointer to the next node in the list. */
} NODE;
typedef struct list {
NODE *head;  /* Pointer to the first node in the list. */
NODE *tail;  /* Pointer to the last node in the list. */
} LIST;
/* Function prototypes the public interface. */
LIST *new_list(const char *value);
void prepend(LIST *list, const char *value);
void append(LIST *list, const char *value);
void delete_list(LIST *list);
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "list.h"
NODE *new_node(const char *value);
LIST *new_list(const char *value)
{
LIST *list = (LIST*) malloc(sizeof(LIST));
NODE* n = new_node(value);
list->head = n;
list->tail = n;
return list;
}
void prepend(LIST *list, const char *value)
{
NODE* n = new_node(value);
n->next = list->head;
list->head->previous = n;
list->head = n;
}
void append(LIST *list, const char *value)
{
NODE* n = new_node(value);
n->previous = list->tail;
list->tail->next = n;
list->tail = n;
}
void delete_list(LIST *list)
{
NODE* n = list->head;
while(n != list->tail)
{
NODE* next = n->next;
free(n);
n = next;
}
free(n);
free(list);
}
NODE *new_node(const char *value)
{
NODE *node = (NODE*) malloc(sizeof(NODE));
node->value = (char*) malloc((strlen(value) + 1) * sizeof(char));
strcpy(node->value, value);
node->previous = NULL;
node->next = NULL;

return node;
}
void print_list(const LIST *list)
{
/* Print the contents of a list. */
for (NODE *node = list->head; node != NULL; node = node->next) {
printf("%sn", node->value);
}
}
int main()
{
char *middle = "middle";
char *last = "last";
char *first = "first";
LIST* list = new_list(middle);
prepend(list, first);
append(list, last);
print_list(list);
delete_list(list);
print_list(list);
}

你显然不能

delete_list(list);
print_list(list);

删除后列表消失。(此时你调用未定义行为)唯一的其他问题是你没有free()node->value

你可以修改:

void delete_list(LIST *list)
{
NODE* n = list->head;
while(n != list->tail)
{
NODE* next = n->next;
free(n->value);
free(n);
n = next;
}
free (n->value);
free(n);
free(list);
}

你的代码可以正常工作。

内存使用/错误检查

$ valgrind ./bin/list
==9065== Memcheck, a memory error detector
==9065== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9065== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9065== Command: ./bin/list
==9065==
first
middle
last
==9065==
==9065== HEAP SUMMARY:
==9065==     in use at exit: 0 bytes in 0 blocks
==9065==   total heap usage: 8 allocs, 8 frees, 1,130 bytes allocated
==9065==
==9065== All heap blocks were freed -- no leaks are possible
==9065==
==9065== For counts of detected and suppressed errors, rerun with: -v
==9065== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

可选删除列表

您可能会发现以下delete_list()的替代方案更具可读性——由您决定:

void delete_list (LIST *list)
{
NODE *n = list->head;

while (n) {
NODE *victim = n;
n = n->next;
free (victim->value);
free (victim);
}
free (list);
}

最新更新