Hi I'm trying to free the memory that I was allocated in the doubly linked list but when I check it with valgrind I have some error in the free_all function ( I think ) but I don't know how to avoid it.
嗨我正在尝试释放我在双链表中分配的内存,但是当我用valgrind检查它时,我在free_all函数中有一些错误(我想),但我不知道如何避免它。
I think in the free_all function I'm using temp and node pointer wrong or I need to allocate it first and then use them, but when I've tried this method valgrind still gave me some error.
我认为在free_all函数中我使用temp和节点指针错误或者我需要先分配它然后再使用它们,但是当我尝试这种方法时,valgrind仍然给了我一些错误。
#include <stdio.h>
#include <stdlib.h>
/*
to compile it:
gcc -g -Wall -ggdb3 double_linkedlist2.c -o double_linkedlist
to check for memory leak and error:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./double_linkedlist
*/
typedef struct listitem
{
struct listitem *next; // pointer to next item
struct listitem *prev; // pointer to previous item
int data; // some data
} ITEM;
int main (void)
{
// prototype functions
void free_all (ITEM *lst_ptr);
// Variables
ITEM *p_temp, *head;
head = malloc (sizeof (ITEM)); // head will keep first and last element in its pointers
head -> next = head; // the last element in the list (at first head -> next and head -> prev will point to the head)
head -> prev = head; // the first element in the list
for (int i = 0; i < 3; i++)
{
p_temp = malloc (sizeof (ITEM)); // allocate some memory for the new list item
p_temp -> data = i; // set the list item's data to the loop count so that we can see where it is in the list
p_temp -> next = head -> next; // this will insert at the FRONT of the list
head -> next = p_temp; // and set the list head to the newly created list item
p_temp -> prev = head; // this will insert at the BACK of the list
p_temp -> next -> prev = p_temp; // and set the list 'tail' to the newly created item
}
// now let's see what we got going forward
printf ("Going forward\n");
p_temp = head -> next;
while (p_temp != head)
{
printf ("forward list item: current is %p; next is %p; prev is %p; data is %d\n", p_temp, p_temp -> next, p_temp -> prev, p_temp -> data);
p_temp = p_temp -> next;
}
// now let's see what we got going backward
printf ("Going backwards\n");
p_temp = head -> prev;
while (p_temp != head)
{
printf ("backward list item; current is %p; next is %p; prev is %p; data is %d\n", p_temp, p_temp -> next, p_temp -> prev, p_temp -> data);
p_temp = p_temp -> prev;
}
printf ("\n");
free_all (head);
return 0;
}
void free_all (ITEM *head)
{
ITEM *temp, *node;
node = head;
while (node != head -> prev)
{
temp = node;
printf ("freed list item: current is %p; next is %p; prev is %p; data is %d\n", temp, temp -> next, temp -> prev, temp -> data);
node = node -> next;
free (temp);
}
free (node);
free (head);
}
2 个解决方案
#1
1
your free_all has at least two errors: the while condition references head->prev, but in the first iteration you free head (use after free). after you exit the loop, you free head despite having free'd it in the first iteration. free_all() does work for the single element case.
你的free_all至少有两个错误:while条件引用head-> prev,但是在第一次迭代中你释放头(免费后使用)。退出循环后,尽管在第一次迭代中已将其释放,但您仍然可以释放头部。 free_all()确实适用于单个元素的情况。
#2
0
There was no error or memory leak in valgrind after this modification
修改后,valgrind中没有错误或内存泄漏
void free_all (ITEM *head)
{
ITEM *temp, *node = NULL;
node = head -> next;
while (node != head -> prev)
{
temp = node;
printf ("freed list item: current is %p; next is %p; prev is %p; data is %d\n", node, node -> next, node -> prev, node -> data);
node = node -> next;
free (temp);
}
node = head -> prev;
printf ("freed list item: current is %p; next is %p; prev is %p; data is %d\n", node, node -> next, node -> prev, node -> data);
free (head);
free (node);
}
#1
1
your free_all has at least two errors: the while condition references head->prev, but in the first iteration you free head (use after free). after you exit the loop, you free head despite having free'd it in the first iteration. free_all() does work for the single element case.
你的free_all至少有两个错误:while条件引用head-> prev,但是在第一次迭代中你释放头(免费后使用)。退出循环后,尽管在第一次迭代中已将其释放,但您仍然可以释放头部。 free_all()确实适用于单个元素的情况。
#2
0
There was no error or memory leak in valgrind after this modification
修改后,valgrind中没有错误或内存泄漏
void free_all (ITEM *head)
{
ITEM *temp, *node = NULL;
node = head -> next;
while (node != head -> prev)
{
temp = node;
printf ("freed list item: current is %p; next is %p; prev is %p; data is %d\n", node, node -> next, node -> prev, node -> data);
node = node -> next;
free (temp);
}
node = head -> prev;
printf ("freed list item: current is %p; next is %p; prev is %p; data is %d\n", node, node -> next, node -> prev, node -> data);
free (head);
free (node);
}