Valgrind Reports Invalid Realloc - c

I'm trying to backfill my knowledge of C memory management. I've come from a mostly scripting and managed background, and I want to learn more about C and C++. To that end I've been reading a few books, including one which included this example of using realloc to trim a string of whitespace:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* trim(char* phrase)
{
char* old = phrase;
char* new = phrase;
while(*old == ' ') {
old++;
}
while(*old) {
*(new++) = *(old++);
}
*new = 0;
return (char*)realloc(phrase, strlen(phrase)+1);
}
int main ()
{
char* buffer = (char*)malloc(strlen(" cat")+1);
strcpy(buffer, " cat");
printf("%s\n", trim(buffer));
free(buffer);
buffer=NULL;
return 0;
}
I dutifully copied the example, and compiled with c99 -Wall -Wpointer-arith -O3 -pedantic -march=native. I don't get any compile errors, and the app runs and does what's promised in the book, but when I run it against valgrind I get an error about invalid realloc.
==21601== Memcheck, a memory error detector
==21601== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==21601== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==21601== Command: ./trim
==21601==
==21601== Invalid free() / delete / delete[] / realloc()
==21601== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==21601== by 0x804844E: main (in /home/mo/programming/learning_pointers/trim)
==21601== Address 0x4202028 is 0 bytes inside a block of size 6 free'd
==21601== at 0x402C324: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==21601== by 0x80485A9: trim (in /home/mo/programming/learning_pointers/trim)
==21601== by 0x804842E: main (in /home/mo/programming/learning_pointers/trim)
==21601==
==21601==
==21601== HEAP SUMMARY:
==21601== in use at exit: 4 bytes in 1 blocks
==21601== total heap usage: 2 allocs, 2 frees, 10 bytes allocated
==21601==
==21601== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==21601== at 0x402C324: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==21601== by 0x80485A9: trim (in /home/mo/programming/learning_pointers/trim)
==21601== by 0x804842E: main (in /home/mo/programming/learning_pointers/trim)
==21601==
==21601== LEAK SUMMARY:
==21601== definitely lost: 4 bytes in 1 blocks
==21601== indirectly lost: 0 bytes in 0 blocks
==21601== possibly lost: 0 bytes in 0 blocks
==21601== still reachable: 0 bytes in 0 blocks
==21601== suppressed: 0 bytes in 0 blocks
==21601==
==21601== For counts of detected and suppressed errors, rerun with: -v
==21601== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
So please help me understand why it's consider an invalid realloc. Is the example crap? Is there something I'm missing? I know that according to the specs, realloc expects the pointer to have been created previously by malloc, so is it because the realloc is in another function? Or is valgrind confused because they're in separate functions? I'm not a complete idiot (most days), but right now I kind of feel like one for not seeing the issue.
Thanks in advance!

You're trying to free the original pointer, not the reallocd one. You can fix it by:
buffer = trim(buffer)

Related

Memory leak when using readline in joined or detached thread

For the past 2 hours or so, I have been trying to figure out why the following code throws a "possibly lost" memory leak:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <readline/readline.h>
#include <readline/history.h>
void *my_read(void* arg) {
char* buf;
if ((buf = readline(">> ")) != NULL) {
printf("Test\n");
if (strlen(buf) > 0) {
add_history(buf);
}
free(buf);
}
pthread_exit(0);
}
int main(int argc, char** argv) {
rl_catch_signals = 0;
pthread_t thread;
pthread_create(&thread, NULL, my_read, NULL);
pthread_join(thread, NULL);
return 0;
}
And I have also tried using detach instead of join, but the result is the same, which is:
==1498903== 272 bytes in 1 blocks are possibly lost in loss record 31 of 78
==1498903== at 0x4849C0F: calloc (vg_replace_malloc.c:1328)
==1498903== by 0x4012662: allocate_dtv (in /lib64/ld-linux-x86-64.so.2)
==1498903== by 0x401309D: _dl_allocate_tls (in /lib64/ld-linux-x86-64.so.2)
==1498903== by 0x497FAA4: pthread_create##GLIBC_2.34 (in /lib64/libc.so.6)
==1498903== by 0x10927B: main (in /home/user/readline)
I have also tried just straight up allocating memory and freeing it in a loop, which shows the same result.
EDIT: Picked the read -> my_read fix from Ajay, but the main issue still remains.
The main problem here is that you have defined a function named read. Readline internally calls the read function to read from stdin. This ends up recursively calling your read function leading to a stackoverflow and crashing your program. The crashed program doesn't free memory for the pthread_t state which should be done when you call pthread_join. This is the main reason valgrind complains.
A simple fix is to read --> my_read.
With the proposed fix the output of valgrind --leak-check=full on my end is -
==27167== Memcheck, a memory error detector
==27167== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==27167== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==27167== Command: ./test
==27167==
>> hello
Test
==27167==
==27167== HEAP SUMMARY:
==27167== in use at exit: 134,297 bytes in 195 blocks
==27167== total heap usage: 316 allocs, 121 frees, 155,633 bytes allocated
==27167==
==27167== LEAK SUMMARY:
==27167== definitely lost: 0 bytes in 0 blocks
==27167== indirectly lost: 0 bytes in 0 blocks
==27167== possibly lost: 0 bytes in 0 blocks
==27167== still reachable: 134,297 bytes in 195 blocks
==27167== suppressed: 0 bytes in 0 blocks
==27167== Reachable blocks (those to which a pointer was found) are not shown.
==27167== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==27167==
==27167== For counts of detected and suppressed errors, rerun with: -v
==27167== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Simple examples to the different leak types reported by Valgrind

While debugging a leaky application, I noticed many, many questions regarding valgrind and the different types of leaks. These questions usually have very specific examples that don't help understanding how the different types of leaks come to be. A reference is this read the manual answer.
What are the mcve for valgrind?
I set out to write a set of very simple functions that show the different types of leaks reported by valgrind and what they mean.
My main source was this Red Hat blog post by Mark Wielaard, I just decided to use simpler examples.
test.c is:
#include <stdlib.h>
#include <string.h>
void leaky_definitely(void)
{
char *p;
/*
This is definitely lost because the pointer is a local variable and once we
exit the function we lose the refence to the allocated block, so there's no
way to free this block.
*/
p = malloc(sizeof(char));
}
char *g_p;
void leaky_still_reachable(void)
{
/*
This is still reachable because the pointer is a global variable that's
preserved until the end of our program, so we could have called free on it.
*/
g_p = malloc(sizeof(char));
}
char *leaky_array;
void leaky_possibly(void)
{
leaky_array = malloc(3*sizeof(char));
/*
This is possibly lost because the allocated base pointer was lost as we
incremented it twice, but because leaky_array still points somwewhere in the
allocated block, we could have done something to recover the base pointer
and then free it.
To transform this possibly lost leak into a definitely lost leak, just
change '2' to '3' in the loop.
*/
for(int i = 0; i < 2; i++) {
*leaky_array = i;
leaky_array++;
}
}
char **double_pointer;
void leaky_indirectly(void)
{
double_pointer = malloc(sizeof(char*));
*double_pointer = malloc(sizeof(char));
/*
This will cause a definitely lost leak because double_pointer is lost. It
will also cause an indirectly lost leak because double_pointer contined a
pointer to another memory block.
Indirectly lost leaks are definitely lost leaks indirectly caused by another
definitely lost leak.
*/
/*
By changing the line bellow to `free(double_pointer)` we would create a
definitely lost leak on `*double_pointer` instead of a indirectly lost.
*/
// free(double_pointer);
double_pointer = NULL;
}
int main(void)
{
leaky_definitely();
leaky_still_reachable();
leaky_possibly();
leaky_indirectly();
return 0;
}
The code was built with:
gcc -Wall -O0 -g -o test test.c
Valgrind was run as
$ valgrind --show-reachable=yes --leak-check=full ./test
==26907== Memcheck, a memory error detector
==26907== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==26907== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==26907== Command: ./test
==26907==
==26907==
==26907== HEAP SUMMARY:
==26907== in use at exit: 14 bytes in 5 blocks
==26907== total heap usage: 5 allocs, 0 frees, 14 bytes allocated
==26907==
==26907== 1 bytes in 1 blocks are still reachable in loss record 1 of 5
==26907== at 0x4C336AD: malloc (vg_replace_malloc.c:381)
==26907== by 0x400518: leaky_still_reachable (test.c:24)
==26907== by 0x4005BF: main (test.c:74)
==26907==
==26907== 1 bytes in 1 blocks are indirectly lost in loss record 2 of 5
==26907== at 0x4C336AD: malloc (vg_replace_malloc.c:381)
==26907== by 0x40059B: leaky_indirectly (test.c:53)
==26907== by 0x4005C9: main (test.c:76)
==26907==
==26907== 1 bytes in 1 blocks are definitely lost in loss record 3 of 5
==26907== at 0x4C336AD: malloc (vg_replace_malloc.c:381)
==26907== by 0x400503: leaky_definitely (test.c:13)
==26907== by 0x4005BA: main (test.c:73)
==26907==
==26907== 3 bytes in 1 blocks are possibly lost in loss record 4 of 5
==26907== at 0x4C336AD: malloc (vg_replace_malloc.c:381)
==26907== by 0x400534: leaky_possibly (test.c:31)
==26907== by 0x4005C4: main (test.c:75)
==26907==
==26907== 9 (8 direct, 1 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5
==26907== at 0x4C336AD: malloc (vg_replace_malloc.c:381)
==26907== by 0x400583: leaky_indirectly (test.c:52)
==26907== by 0x4005C9: main (test.c:76)
==26907==
==26907== LEAK SUMMARY:
==26907== definitely lost: 9 bytes in 2 blocks
==26907== indirectly lost: 1 bytes in 1 blocks
==26907== possibly lost: 3 bytes in 1 blocks
==26907== still reachable: 1 bytes in 1 blocks
==26907== suppressed: 0 bytes in 0 blocks
==26907==
==26907== For lists of detected and suppressed errors, rerun with: -s
==26907== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

Copying a string - how do I have to deal with memory leaks and error cases?

I am trying to implement the function int *cpy_array(int v[], int size), which copies the array in another and returns the new array as pointer. I also have to watch out for error cases and use dynamic memory.
Ok i know that malloc returns 0 when there is nout enough memory available. I was wondering if there might be any other possible errors as well which I missed out. Then I have to implement free() in the case of succsess as well as in error case.
I tried to implement something like:
if (!w[i]) {
for (k = 0; k < i; ++k)
free(w[k]);
return 0;
}
But there was always an error with this.
In file included from hot.c:2:
C:/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/i686-w64-mingw32/include/stdlib.h:502:27: note: expected 'void *' but argument is of type 'int'"
void __cdecl free(void *_Memory);
And I am not sure why to free() the new array or should the old array be freed? I tried to free it with pointer in my function, but didnt work either and dont think it should be in the main?
Here is the original code:
int *cpy_array(int v[], int size);
int main(void)
{
int size;
size = 4;
int myArray[4] = {1234};
if (*cpy_array(myArray, size) == 0)
{
printf("No memory available.");
}else{
printf("The new Array: %i", *cpy_array(myArray, size));
}
return 0;
}
int *cpy_array(int v[], int size)
{
int i;
int *a = malloc(size * sizeof(int));
if(*a == 0)
return 0;
for (i = 0; i < size; i++)
{
a[i] = v[i];
}
return a;
}
In your first code snippet, you incorrectly deallocated the array of integers w. You can't free single integers in that array, but what you need to do is simply type in:
free(w);
That will free the entire array.
You can also see from the text of the error - note: expected 'void *' but argument is of type 'int'" void __cdecl free(void *_Memory), that the program expected a pointer to the array and not an integer.
You can't free the old array, because it's statically created and the memory for it allocated at the start of the program and it will be freed at the end of the function in which it was defined by the program itself, so you don't need to worry about that. Whereas it's your job to free the dynamically created arrays such as the one you created through the cpy_array(int v[], int size) function.
More on the difference between static and dynamic allocation, you can look up here:
Difference between static memory allocation and dynamic memory allocation
This part of code, wouldn't proparly print the array (you will just print the first number of the array), and also you are calling the function twice, which is excessive and should be done only once for the same array.
if (*cpy_array(myArray, size) == 0)
{
printf("No memory available.");
}else{
printf("The new Array: %i", *cpy_array(myArray, size));
}
You could easify fix these problems by defining a pointer which could store the return value of the function, so you don't have to call it twice and then to correctly print the array use a for loop:
int * copiedArray = cpy_array(myArray, size);
if (copiedArray == NULL)
{
printf("No memory available.");
}else{
printf("The new Array: ");
for (int i = 0; i < size; i++)
printf("%i ", copiedArray[i]);
}
I noticed that you are checking whether a pointer is pointing to something or not incorrectly. Once in main:
if (*cpy_array(myArray, size) == 0)
And once in the cpy_array(int v[], int size) function:
if(*a == 0)
This will not work because you are dereferencing the pointer and checking whether the value to which it is pointing is zero. What you want to do is check the value of the pointer itself. If that is NULL then the allocation didn't work:
if (cpy_array(myArray, size) == NULL)
and
if(a == NULL)
You should use NULL instead of zero because you are explicitly stating that you are checking a value of a pointer, and NULL may not be equal to zero on every machine.
More on that topic here:
What is the difference between NULL, '\0' and 0
To detect you problems concerning the memory use valgrind, If I do that gives :
==10947== Memcheck, a memory error detector
==10947== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10947== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==10947== Command: ./a.out
==10947==
==10947== Conditional jump or move depends on uninitialised value(s)
==10947== at 0x10548: cpy_array (c.c:25)
==10947== by 0x104B3: main (c.c:11)
==10947==
==10947== Invalid read of size 4
==10947== at 0x104B8: main (c.c:11)
==10947== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==10947==
==10947==
==10947== Process terminating with default action of signal 11 (SIGSEGV)
==10947== Access not within mapped region at address 0x0
==10947== at 0x104B8: main (c.c:11)
==10947== If you believe this happened as a result of a stack
==10947== overflow in your program's main thread (unlikely but
==10947== possible), you can try to increase the size of the
==10947== main thread stack using the --main-stacksize= flag.
==10947== The main thread stack size used in this run was 8388608.
==10947==
==10947== HEAP SUMMARY:
==10947== in use at exit: 16 bytes in 1 blocks
==10947== total heap usage: 1 allocs, 0 frees, 16 bytes allocated
==10947==
==10947== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==10947== at 0x4847568: malloc (vg_replace_malloc.c:299)
==10947== by 0x10533: cpy_array (c.c:24)
==10947== by 0x104B3: main (c.c:11)
==10947==
==10947== LEAK SUMMARY:
==10947== definitely lost: 16 bytes in 1 blocks
==10947== indirectly lost: 0 bytes in 0 blocks
==10947== possibly lost: 0 bytes in 0 blocks
==10947== still reachable: 0 bytes in 0 blocks
==10947== suppressed: 0 bytes in 0 blocks
==10947==
==10947== For counts of detected and suppressed errors, rerun with: -v
==10947== Use --track-origins=yes to see where uninitialised values come from
==10947== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 6 from 3)
The "Conditional jump or move depends on uninitialised value(s)" comes from the *a in if(*a == 0) and "Invalid read of size 4 ..." because you dereference 0 because of the return 0;
after changing if(*a == 0) to if(a == 0) to solve the two previous problems that condition is (a priori) false and _valgrind says :
==11116== Memcheck, a memory error detector
==11116== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11116== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11116== Command: ./a.out
==11116==
Mein neuer Array enthaelt folgende Zeichen: 1==11116==
==11116== HEAP SUMMARY:
==11116== in use at exit: 32 bytes in 2 blocks
==11116== total heap usage: 3 allocs, 1 frees, 1,056 bytes allocated
==11116==
==11116== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==11116== at 0x4847568: malloc (vg_replace_malloc.c:299)
==11116== by 0x10523: cpy_array (c.c:24)
==11116== by 0x104A3: main (c.c:11)
==11116==
==11116== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==11116== at 0x4847568: malloc (vg_replace_malloc.c:299)
==11116== by 0x10523: cpy_array (c.c:24)
==11116== by 0x104CF: main (c.c:15)
==11116==
==11116== LEAK SUMMARY:
==11116== definitely lost: 32 bytes in 2 blocks
==11116== indirectly lost: 0 bytes in 0 blocks
==11116== possibly lost: 0 bytes in 0 blocks
==11116== still reachable: 0 bytes in 0 blocks
==11116== suppressed: 0 bytes in 0 blocks
==11116==
==11116== For counts of detected and suppressed errors, rerun with: -v
==11116== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 6 from 3)
so yes you have memory leaks because you lost 2 times the allocation return by cpy_array
you need to have something like :
int * v = cpy_array(myArray, size);
if (*v == 0)
{
printf("Speicher kann nicht freigegeben werden.");
}else{
printf("Mein neuer Array enthaelt folgende Zeichen: %i",
*v);
}
free(v);
Doing that correction valgrind signals nothing :
valgrind --leak-check=full ./a.out
==11224== Memcheck, a memory error detector
==11224== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11224== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11224== Command: ./a.out
==11224==
Mein neuer Array enthaelt folgende Zeichen: 1==11224==
==11224== HEAP SUMMARY:
==11224== in use at exit: 0 bytes in 0 blocks
==11224== total heap usage: 2 allocs, 2 frees, 1,040 bytes allocated
==11224==
==11224== All heap blocks were freed -- no leaks are possible
==11224==
==11224== For counts of detected and suppressed errors, rerun with: -v
==11224== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
I encourage you to
compile with all warning detection, like gcc -g -Wall -pedantic ...
when you have problem use valgrind and/or debugger
even you do not see a problem run anyway under valgrind, so problems can be hidden
this is not the correct way to initialize the array
int myArray[4] = {1234};
write
int myArray[4] = { 1,2,3,4 };
or simply
int myArray[] = { 1,2,3,4 };
Calling the function cpy_array .. when you write
if (*cpy_array(myArray, size) == 0)
Is not correct, why? because what if the function returns NULL, then you are dereferencing NULL
In your function cpy_array you are dereferencing a, that is not correct, instead compare the pointer
if ( a == NULL)
and use the standard constant NULL for a null pointer instead of 0 since it may not be 0 on all platforms.

Why does Valgrind show a memory leak on a calloc statement

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?
origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
By doing this you change to what origstr points to . After this origstr doesn't point to memory block allocated by calloc .
And you free memory not allocated by calloc or similar functions , thus causing error in your program.
Use strcpy to copy string to origstr -
strcpy(origstr,"TheQuickBrownFoxJumpedOverTheLazyDog");
and then you can free your pointer origstr.
By assigning the string literal to origstr you don't copy the string but just change origstrs value, thus losing the pointer to calloc. freeing origstr now causes undefined behavior.
Use strcpy or strncpy instead to really store the string on the heap. But actually dropping calloc for origstr should suffice.
Notes:
as #LeeDanielCrocker mentioned in the comments to this answer, you probably intended to allocate space for chars, not for char*s, decreasing the size of the allocated memory drastically. You should replace the sizeof(char*) with a sizeof(char) (a.k.a. 1).
Because there is a memory leak. You reassign the pointer, it's actually incorrect to free() it as you have it.
To copy the contents to the allocated pointer use strcpy()
strcpy(origstr, "TheQuickBrownFoxJumpedOverTheLazyDog");
Let's see how:
You request memory with calloc()
origstring = calloc(9, sizeof(char*))
this is wrong for multiple reasons
You are allocating space for 9 pointers, not 9 characters.
You don't really need calloc() because you will overwrite the contents immediately, use malloc().
You overwrite the pointer with a string literal
origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
now you lost reference to the pointer returned earlier by calloc() and you cannot possible free() it, you should only free() pointers return by malloc()/calloc()/realloc().
The truth is, you don't need to calloc() the oristring pointer, calloc()/malloc() are not used to allow you to assign to a pointer, but to write to the memory pointed to by the pointer, or better, to point to some memory you can read/write from/to.

Definitely Lost Memory Leak in C Program

Would someone be able to shed light on why Valgrind classifies this program as a "Definitely Lost: 2 bytes in 1 block" memory leak? I understand that the commented line resolves the issue, but I don't understand the classification. According to Valgrind docs it appears that the memory leak should be classified as "Indirectly Reachable". I am also curious as to why this is even considered a memory leak and would appreciate an explanation. Is it good practice to manually free everything even though the program is terminating at the end of the main function?
#include <stdlib.h>
struct wrapper {
char *data;
};
char *strdup(const char *);
struct wrapper *walloc(struct wrapper *root)
{
if (root == NULL){
root = (struct wrapper *) malloc(sizeof(struct wrapper));
root->data = strdup("H");
}
return root;
}
int main(){
struct wrapper *root;
root = NULL;
root = walloc(root);
//free(root->data);
return 0;
}
Here is the Valgrind output:
$ valgrind --leak-check=full ./leak
==26489== Memcheck, a memory error detector
==26489== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==26489== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==26489== Command: ./leak
==26489==
==26489==
==26489== HEAP SUMMARY:
==26489== in use at exit: 2 bytes in 1 blocks
==26489== total heap usage: 2 allocs, 1 frees, 1,790 bytes allocated
==26489==
==26489== 2 bytes in 1 blocks are definitely lost in loss record 1 of 1
==26489== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26489== by 0x4EB79C9: strdup (in /usr/lib/libc-2.20.so)
==26489== by 0x400542: walloc (leak.c:13)
==26489== by 0x400542: main (leak.c:23)
==26489==
==26489== LEAK SUMMARY:
==26489== definitely lost: 2 bytes in 1 blocks
==26489== indirectly lost: 0 bytes in 0 blocks
==26489== possibly lost: 0 bytes in 0 blocks
==26489== still reachable: 0 bytes in 0 blocks
==26489== suppressed: 0 bytes in 0 blocks
==26489==
==26489== For counts of detected and suppressed errors, rerun with: -v
==26489== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
strdup allocates memory on the heap (using malloc) and therefore you need to free this memory when it's no longer in use like for anyone of your own direct call to malloc.
You must do that even when the program finish because this is the only way to detect a memory leak. Of course, the notion of checking for any memory leak might seem a little overkill when a program finish because all of its allocated memory is then automatically released by the OS but don't forget that your small program is an exception here. Usually, most programs will take a very large amount of memory when running and might run out of memory or run much slower if there are multiple memory leaks inside them.
Even a small program should be well written; otherwise it will become impossible for you to write any big programs later because your bad habits will translate into a tons of coding errors.
Thanks to #sharth for pointing me in the right direction. The Direct Loss was actually properly detected by Valgrind, but was confusing due to the -O3 compilation which removed root entirely. Compiling without -O3 shows the proper direct loss of 8 bytes and indirect loss of 2 bytes.
Also, thanks to #SylvainL and #Lundin for their best practices comments.
FYI: The corrected Valgrind output looks like this:
==30492== Memcheck, a memory error detector
==30492== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==30492== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==30492== Command: ./leak
==30492==
==30492==
==30492== HEAP SUMMARY:
==30492== in use at exit: 10 bytes in 2 blocks
==30492== total heap usage: 3 allocs, 1 frees, 1,830 bytes allocated
==30492==
==30492== 10 (8 direct, 2 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==30492== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30492== by 0x400687: walloc (leak.c:12)
==30492== by 0x4006C6: main (leak.c:23)
==30492==
==30492== LEAK SUMMARY:
==30492== definitely lost: 8 bytes in 1 blocks
==30492== indirectly lost: 2 bytes in 1 blocks
==30492== possibly lost: 0 bytes in 0 blocks
==30492== still reachable: 0 bytes in 0 blocks
==30492== suppressed: 0 bytes in 0 blocks
==30492==
==30492== For counts of detected and suppressed errors, rerun with: -v
==30492== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Resources