I am trying to learn a couple things (like a hobby) and trying to learn how to use Valgrind. However, this does not make sense to me. Valgrind seems to say that bytes are lost when I allocate their calloc before I even use anything! Can someone explain what is happening here and why did the second program work? I compiled the programs in debug mode in Eclipse and ran Valgrind in the debug executable.
Here is the program:
1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <string.h> 4 5 int main(void) { 6 7 char* origstr = calloc(37, sizeof(char*)); 8 char* newsubstr = calloc(9, sizeof(char*)); 9 10 origstr = "TheQuickBrownFoxJumpedOverTheLazyDog"; 11 12 strncpy(newsubstr, origstr + 8, 8); 13 printf("SubString is: %s\n", newsubstr); 14 15 free(newsubstr); 16 free(origstr); 17 return 0; 18 }
And here is what Walgrind gives me:
$ valgrind --tool=memcheck --leak-check=full ./test ==25404== Memcheck, a memory error detector ==25404== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==25404== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info ==25404== Command: ./test ==25404== SubString is: BrownFox ==25404== Invalid free() / delete / delete[] / realloc() ==25404== at 0x4C29E90: free (vg_replace_malloc.c:473) ==25404== by 0x400665: main (test.c:16) ==25404== Address 0x4006f8 is not stack'd, malloc'd or (recently) free'd ==25404== ==25404== ==25404== HEAP SUMMARY: ==25404== in use at exit: 296 bytes in 1 blocks ==25404== total heap usage: 2 allocs, 2 frees, 368 bytes allocated ==25404== ==25404== 296 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==25404== at 0x4C2AD10: calloc (vg_replace_malloc.c:623) ==25404== by 0x4005FC: main (test.c:7) ==25404== ==25404== LEAK SUMMARY: ==25404== definitely lost: 296 bytes in 1 blocks ==25404== indirectly lost: 0 bytes in 0 blocks ==25404== possibly lost: 0 bytes in 0 blocks ==25404== still reachable: 0 bytes in 0 blocks ==25404== suppressed: 0 bytes in 0 blocks ==25404== ==25404== For counts of detected and suppressed errors, rerun with: -v ==25404== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
If I remove the two free () statements, this is what Valgrind gives me:
$ valgrind --tool=memcheck --leak-check=full ./test ==25597== Memcheck, a memory error detector ==25597== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==25597== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info ==25597== Command: ./test ==25597== SubString is: BrownFox ==25597== ==25597== HEAP SUMMARY: ==25597== in use at exit: 368 bytes in 2 blocks ==25597== total heap usage: 2 allocs, 0 frees, 368 bytes allocated ==25597== ==25597== 72 bytes in 1 blocks are definitely lost in loss record 1 of 2 ==25597== at 0x4C2AD10: calloc (vg_replace_malloc.c:623) ==25597== by 0x4005BF: main (test.c:8) ==25597== ==25597== 296 bytes in 1 blocks are definitely lost in loss record 2 of 2 ==25597== at 0x4C2AD10: calloc (vg_replace_malloc.c:623) ==25597== by 0x4005AC: main (test.c:7) ==25597== ==25597== LEAK SUMMARY: ==25597== definitely lost: 368 bytes in 2 blocks ==25597== indirectly lost: 0 bytes in 0 blocks ==25597== possibly lost: 0 bytes in 0 blocks ==25597== still reachable: 0 bytes in 0 blocks ==25597== suppressed: 0 bytes in 0 blocks ==25597== ==25597== For counts of detected and suppressed errors, rerun with: -v ==25597== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Now, if I run this program:
1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <string.h> 4 5 int main(void) { 6 7 char* origstr; 8 char* newsubstr = calloc(9, sizeof(char*)); 9 10 origstr = "TheQuickBrownFoxJumpedOverTheLazyDog"; 11 12 strncpy(newsubstr, origstr + 8, 8); 13 printf("SubString is: %s\n", newsubstr); 14 15 free(newsubstr); 16 17 return 0; 18 }
This shows that everything is fine:
$ valgrind --tool=memcheck --leak-check=full ./test ==25862== Memcheck, a memory error detector ==25862== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==25862== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info ==25862== Command: ./test ==25862== SubString is: BrownFox ==25862== ==25862== HEAP SUMMARY: ==25862== in use at exit: 0 bytes in 0 blocks ==25862== total heap usage: 1 allocs, 1 frees, 72 bytes allocated ==25862== ==25862== All heap blocks were freed -- no leaks are possible ==25862== ==25862== For counts of detected and suppressed errors, rerun with: -v ==25862== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Why can't I calloc (highlight) origstr and then give it something? What if I would like to isolate this variable and during the program give it part of what is in another string variable, or use it to capture the result of another function that returns a string? Should I then handle this as if I did newsubstr?
This is a bit confusing to me, so can someone explain how this works so that I can better understand?