|
From: Joachim Z. <zi...@mp...> - 2008-09-17 15:27:32
|
Hello list,
can you please explain to me what I misunderstand in the following:
I wrote a little C program that first creates a linked list with 100
list elements and then deletes these elements. There is nothing special
about it:
-----------------------------------------------------------------
#include <stdlib.h>
typedef struct listelement {
struct listelement *next;
} node;
int main()
{
int i;
node *head = (node*) malloc(sizeof(node)); /* head of list */
node *tail = head; /* tail of list */
/* insert 99 nodes into list (at the end) */
for(i = 1; i < 100; i++) {
node *p = (node*) malloc(sizeof(node)); /* new list node */
p->next = NULL;
tail->next = p;
tail = p;
}
/* delete all 100 nodes from list */
while(head != NULL) {
node *p = head->next;
free(head);
head = p;
}
}
------------------------------------------------------------------------
Running Valgrind (memcheck) on this program outputs what I have expected:
$ valgrind --leak-check=full valgrindtest_d
==5271== Memcheck, a memory error detector.
==5271== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==5271== Using LibVEX rev 1732, a library for dynamic binary translation.
==5271== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==5271== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==5271== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==5271== For more details, rerun with: -v
==5271==
==5271==
==5271== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 1)
==5271== malloc/free: in use at exit: 0 bytes in 0 blocks.
==5271== malloc/free: 100 allocs, 100 frees, 400 bytes allocated.
==5271== For counts of detected errors, rerun with: -v
==5271== All heap blocks were freed -- no leaks are possible.
But now, if I comment out the while loop (i.e., I fill the list but do
not empty it)
// while(head != NULL) {
// node *p = head->next;
// free(head);
// head = p;
// }
Valgrind says:
=5278== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 1)
==5278== malloc/free: in use at exit: 400 bytes in 100 blocks.
==5278== malloc/free: 100 allocs, 0 frees, 400 bytes allocated.
==5278== For counts of detected errors, rerun with: -v
==5278== searching for pointers to 100 not-freed blocks.
==5278== checked 119,852 bytes.
==5278==
==5278== 400 (4 direct, 396 indirect) bytes in 1 blocks are definitely
lost in loss record 1 of 2
==5278== at 0x40235B5: malloc (in
/usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==5278== by 0x8048470: main (valgrindtest.c:12)
==5278==
==5278== LEAK SUMMARY:
==5278== definitely lost: 4 bytes in 1 blocks.
==5278== indirectly lost: 396 bytes in 99 blocks.
==5278== possibly lost: 0 bytes in 0 blocks.
==5278== still reachable: 0 bytes in 0 blocks.
==5278== suppressed: 0 bytes in 0 blocks.
How can this be? How can 400 bytes be "definitely lost"? My "head"
pointer still points to the head element of the list, so I still can
reach all elements!
The manual says: "Definitely lost, or "leaked": The worst outcome is
that no pointer to the block can be found. The block is classified as
"leaked", because the programmer could not possibly have freed it at
program exit, since no pointer to it exists. This is likely a symptom of
having lost the pointer at some earlier point in the program."
Of course I have a pointer (head) with which I can free everything I've
malloc'd!
Can someone please explain this to me?
Thank you,
Joachim
|
|
From: Julian S. <js...@ac...> - 2008-09-17 15:39:56
|
> Of course I have a pointer (head) with which I can free everything I've > malloc'd! Once main has returned, you definitely don't have "head" available to free the list, so the memory really is lost. The leak checker runs when your program is finished; that is, after main has returned. J |
|
From: Edward M. <em...@li...> - 2008-09-17 16:27:25
|
Joachim Ziegler wrote:
> Hello list,
>
> can you please explain to me what I misunderstand in the following:
>
> I wrote a little C program that first creates a linked list with 100
> list elements and then deletes these elements. There is nothing special
> about it:
>
> -----------------------------------------------------------------
> #include <stdlib.h>
>
> typedef struct listelement {
> struct listelement *next;
> } node;
>
> int main()
> {
> int i;
> node *head = (node*) malloc(sizeof(node)); /* head of list */
> node *tail = head; /* tail of list */
>
> /* insert 99 nodes into list (at the end) */
>
> for(i = 1; i < 100; i++) {
> node *p = (node*) malloc(sizeof(node)); /* new list node */
> p->next = NULL;
> tail->next = p;
> tail = p;
> }
>
> /* delete all 100 nodes from list */
>
> while(head != NULL) {
> node *p = head->next;
> free(head);
> head = p;
> }
> }
> ------------------------------------------------------------------------
>
>
> Running Valgrind (memcheck) on this program outputs what I have expected:
>
>
> $ valgrind --leak-check=full valgrindtest_d
> ==5271== Memcheck, a memory error detector.
> ==5271== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
> ==5271== Using LibVEX rev 1732, a library for dynamic binary translation.
> ==5271== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
> ==5271== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
> ==5271== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
> ==5271== For more details, rerun with: -v
> ==5271==
> ==5271==
> ==5271== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 1)
> ==5271== malloc/free: in use at exit: 0 bytes in 0 blocks.
> ==5271== malloc/free: 100 allocs, 100 frees, 400 bytes allocated.
> ==5271== For counts of detected errors, rerun with: -v
> ==5271== All heap blocks were freed -- no leaks are possible.
>
>
> But now, if I comment out the while loop (i.e., I fill the list but do
> not empty it)
>
> // while(head != NULL) {
> // node *p = head->next;
> // free(head);
> // head = p;
> // }
>
> Valgrind says:
>
> =5278== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 1)
> ==5278== malloc/free: in use at exit: 400 bytes in 100 blocks.
> ==5278== malloc/free: 100 allocs, 0 frees, 400 bytes allocated.
> ==5278== For counts of detected errors, rerun with: -v
> ==5278== searching for pointers to 100 not-freed blocks.
> ==5278== checked 119,852 bytes.
> ==5278==
> ==5278== 400 (4 direct, 396 indirect) bytes in 1 blocks are definitely
> lost in loss record 1 of 2
> ==5278== at 0x40235B5: malloc (in
> /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
> ==5278== by 0x8048470: main (valgrindtest.c:12)
> ==5278==
> ==5278== LEAK SUMMARY:
> ==5278== definitely lost: 4 bytes in 1 blocks.
> ==5278== indirectly lost: 396 bytes in 99 blocks.
> ==5278== possibly lost: 0 bytes in 0 blocks.
> ==5278== still reachable: 0 bytes in 0 blocks.
> ==5278== suppressed: 0 bytes in 0 blocks.
>
> How can this be? How can 400 bytes be "definitely lost"? My "head"
> pointer still points to the head element of the list, so I still can
> reach all elements!
>
> The manual says: "Definitely lost, or "leaked": The worst outcome is
> that no pointer to the block can be found. The block is classified as
> "leaked", because the programmer could not possibly have freed it at
> program exit, since no pointer to it exists. This is likely a symptom of
> having lost the pointer at some earlier point in the program."
>
> Of course I have a pointer (head) with which I can free everything I've
> malloc'd!
>
>
> Can someone please explain this to me?
>
head is local variable to main. You have returned from main without
freeing the data. When valgrind looks, there is no pointers that are
accessable to free the list.
If head was declared outside of main, you should then see the still
reachable error message instead.
> Thank you,
> Joachim
>
> -------------------------------------------------------------------------
> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>
Ed
|
|
From: Joachim Z. <zi...@mp...> - 2008-09-18 10:12:40
|
Edward Maros wrote: > head is local variable to main. You have returned from main without > freeing the data. When valgrind looks, there is no pointers that are > accessable to free the list. > > If head was declared outside of main, you should then see the still > reachable error message instead. Yes, of course. Thank you. This was clearly a rookie's mistake I made. Joachim |