处理简单的双链表。
struct list_node {
struct list_node *prev, *next;
int data;
};
struct list {
struct list_node *first, *last;
};
创建和推送如下:
struct list *list_create(void) {
struct list *_list = malloc(sizeof(struct list));
if(_list == NULL) {
die("Memory allocation error for list_createn");
}
_list->first = NULL;
_list->last = NULL;
return _list;
}
void list_push(struct list *list, int item_data) {
struct list_node *_node = malloc(sizeof(struct list_node));
if(_node == NULL) {
die("Memory allocation error for list_pushn");
}
_node->prev = NULL;
_node->next = NULL;
_node->data = item_data;
//empty list case
if(list->last == NULL) {
list->first = _node;
list->last = _node;
}
else {
_node->prev = list->last;
list->last->next = _node;
list->last = _node;
}
}
一次推送有效,但连续两次推送会导致节点大小的内存泄漏
我这里缺少什么?
为了完成,这里是我的列表free
,我在代码中称之为:
void list_destroy(struct list *list) {
if (list->first != NULL) {
struct list_node *p = list->first;
//if one node list
if(list->first == list->last) {
list->first = NULL;
list->last = NULL;
free(p);
p = NULL;
}
else {
while (p->next) {
struct list_node *q = p;
p = p->next;
free(q);
q = NULL;
}
}
}
free(list);
}
[SOLVED]Bug在list_destroy
中-上次通过while(p->next)
导致最后一个p
节点未正确处理。谢谢大家!
内存泄漏是由while循环中的函数list_destroy
产生的
while (p->next) {
struct list_node *q = p;
p = p->next;
free(q);
q = NULL;
}
由于while循环的条件,列表的最后一个节点没有释放
while (p->next) {
因为对于最后一个节点,数据成员CCD_ 6等于CCD_。
把功能分成两部分是没有意义的。的功能如下
void list_destroy(struct list *list) {
while ( list->first )
{
struct list_node *p = list->first;
list->first = list->first->next;
free( p );
}
free( list );
}
最好是通过引用通过指向它的指针来传递指针列表,例如
void list_destroy(struct list **list) {
struct list_node *current = ( *list )->first;
while ( current )
{
struct list_node *p = current;
current = current->next;
free( p );
}
free( *list );
*list = NULL;
}
在这种情况下,函数执行后,调用方中指向列表的指针将等于NULL。
您也可以编写一个函数来清除列表。的外观如下
void list_clear(struct list *list) {
while ( list->first )
{
struct list_node *p = list->first;
list->first = list->first->next;
free( p );
}
list->last = NULL;
}
来自莫斯科的弗拉德写了一个更干净的版本。我想加上";防御性编程";。假设create()
在push()
或destroy()
之前被调用是危险的。事实上,您可以避免一个很难找到的错误(在调用代码中使用指针,在它被释放后(((始终检查"传入"参数。
在呼叫代码中:
myList = list_destroy( myList );
并返回一些可以使用的东西。
list_t *list_destroy( list_t *pList ) {
assert( pList != NULL );
// iterate releasing alloc'd blocks...
return NULL;
}