I'm trying to learn a couple things (just as a hobby) and trying to learn to use Valgrind. However this doesn't seem to make sense to me. It seems Valgrind is saying that bytes are lost when I'm allocating them with calloc before I even use anything! Can someone explain what is going on here and why the second program worked? I compiled the programs in debug mode in Eclipse and ran Valgrind on the debug executable.
Here's 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's what Valgrind 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, here's 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 }
It shows everything is just 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 is it that I can't calloc (allocate) origstr and then give it something? What if I wanted to allocate that variable and in the course of the program give it part of what's in another string variable or use it to capture the result of another function that returns a string? Would I then have to handle it like I did newsubstr?
This is a bit confusing to me so can someone explain how this works so I can understand it better?