【发布时间】:2016-10-02 23:02:14
【问题描述】:
我正在用 C 编写一个通用链表(遵循 Kyle Loudon 的书), 但是在释放它时,我遇到了 segfault。
用于列表定义的数据类型:
typedef struct list_elem_
{
void *data;
struct list_elem_ *next;
} list_elem;
typedef struct link_list_
{
int size;
int (*match)(const void *key1, const void *key2);
void (*destroy)(void *data);
list_elem *head;
list_elem *tail;
} link_list;
用于销毁调用者数据的函数:
void destroy_data(void *data)
{
if(data)
free(data);
return;
}
函数指针传递的销毁:
void list_init(link_list *list, void (*destroy)(void *data))
{
list->size = 0;
list->destroy = destroy;
list->head = NULL;
list->tail = NULL;
return;
}
释放列表:
void list_destroy(link_list *list)
{
void* data;
while(list_size(list) > 0)
if(list_rem_next(list, NULL, (void**)&data) == 0 && list->destroy != NULL)
list->destroy(data);
memset(list,0,sizeof(link_list));
return;
}
段错误是由destroy_data中的free触发的。
============== 编辑 =====================
删除列表元素
int list_rem_next(link_list *list, list_elem *element, void **data)
{
list_elem *OldElement;
if(list_size(list) ==0)
return -1;
/* Remove the head */
if(element == NULL)
{
*data = list->head->data;
OldElement = list->head;
list->head = list->head->next;
if(list_size(list) == 1)
list->tail = NULL;
/* Remove other than head */
} else {
if(element->next == NULL)
return -1;
*data = element->data;
OldElement = element->next;
element->next = element->next->next;
if(element->next == NULL)
list->tail = element;
}
free(OldElement);
list->size--;
return 0;
}
=================== 编辑 2 ==========================
主目录
link_list myList;
int i;
int *iptr;
char *chrPtr;
list_init(&myList, destroy_data);
for(i = 0; i < 4; i++)
{
iptr = malloc(sizeof(int));
*iptr = i;
list_ins_next(&myList, NULL, iptr);
}
chrPtr = malloc(sizeof("uno\0"));
chrPtr = "uno\0";
list_ins_next(&myList,NULL,chrPtr);
chrPtr = malloc(sizeof("stringa numero due\0"));
chrPtr = "stringa numero due\0";
list_ins_next(&myList,NULL,chrPtr);
chrPtr = NULL;
iptr = NULL;
getchar();
list_destroy(&myList);
【问题讨论】:
-
void destroy_data(void *data) { if(data) free(data); return; }:: 烧书。 -
发布
list_rem_next的定义 -
list_rem_next的定义是什么 -
您的免费代码可能没有任何问题。您的免费代码假定列表已正确构建,如果确实如此,那很好。这就是为什么发布一个展示问题的完整示例很重要——它可能不是您认为的位置。见sscce.org。
-
啊啊啊啊啊啊!
chrPtr = malloc(sizeof("uno\0")); chrPtr = "uno\0";—— (a) 当 C 自动在它后面加一个时,为什么显式的\0? (b) 你能说“内存泄漏”吗? (c)strcpy()发生了什么事?您将未分配的内存指针传递给free();实际上,您将指向字符串常量的指针传递给free()。这是未定义的行为,很容易导致崩溃!这也是 Greg 提到的 MCVE (minimal reproducible example) 又名 SSCCE(简短、独立、正确的示例)如此重要的原因。问题不在于您最初显示的代码;它在另一个代码中。
标签: c linked-list segmentation-fault free generic-programming