Replace char* in function without memory leak

c, memory, memory-leaks

Solution

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.

Problem

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.

Original source