I'm trying to make a find-and-replace function, and it works, but valgrind reports huge memory leaks.
Have a look:
void repl(char** str) {
// build a new string (simulating find&replace)
char* replacement = (char*)malloc(7);
strcpy(replacement, "my ass");
// this causes "free(): invalid pointer" crash
//free(*str);
*str = replacement; // return to caller
}
/* main function */
int main (int argc, char **argv) {
// out original string
char* str = "memory leak here";
repl(&str); // replace something 1st time
repl(&str); // 2nd time
repl(&str); // 3rd time
printf("%s\n",str); // look at output
exit(0);
}
When the "free" is in place, you will get:
*** glibc detected *** ./test: free(): invalid pointer: 0x0000000000401013 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f264e7ecb96]
....
If the free
is not there, however, you get a memory leak (valgrind output):
==26236== LEAK SUMMARY:
==26236== definitely lost: 14 bytes in 2 blocks
==26236== indirectly lost: 0 bytes in 0 blocks
==26236== possibly lost: 0 bytes in 0 blocks
==26236== still reachable: 7 bytes in 1 blocks
==26236== suppressed: 0 bytes in 0 blocks
I'm not entirely familiar with pointers yet, so please have some patience. Perhaps this is not the best way, so please suggest better method for find-and-replace with no memory leaks.
I tried just returning the result, but then I got leaks as well.
One of the most common mistakes leading to memory leaks is applying the wrong delete operator. The delete operator should be used to free a single allocated class or data value, whereas the delete [] operator should be used to free an array of data values.
To avoid memory leaks, memory allocated on heap should always be freed when no longer needed.
The best way to avoid memory leaks in C++ is to have as few new/delete calls at the program level as possible – ideally NONE. Anything that requires dynamic memory should be buried inside an RAII object that releases the memory when it goes out of scope.
WHAT'S UP WITH glibc
?
The glibc
diagnostic is related to the fact that str
doesn't always point to a memory segment allocated by malloc
, which is one of the requirements of free
. In other words; your first call to repl
with the value of str
pointing to a non-malloced memory segment will cause free
to misbehave.
WHAT'S UP WITH valgrind
?
The valgrind diagnostics are there because of the fact that without your (currently malfunctioning) usage of free
, the memory allocated by malloc
inside repl
is never released, and hence; you are leaking memory.
PROPOSED SOLUTION
I feel like it's better to explain it in words instead of handing you a functioning implementation, since you seems to be eager to learn by doing.
don't accept a pointer-to-pointer-to-char, instead accept a pointer-to-char
and return a pointer to a new memory segment that consists of a modified version of the string passed in. This new memory segment has been allocated through malloc
,
rename your function to make it clear that it is allocating memory that needs to be released,
document your function so that the caller knows that it is responsible for free
ing the memory, not your replace-function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With