Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace char* in function without memory leak

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.

like image 859
MightyPork Avatar asked Mar 22 '14 20:03

MightyPork


People also ask

Which function operator can be used to avoid a memory leak?

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.

How to prevent memory leak?

To avoid memory leaks, memory allocated on heap should always be freed when no longer needed.

How to stop memory leaks in c++?

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.


1 Answers

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.

  1. 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,

  2. rename your function to make it clear that it is allocating memory that needs to be released,

  3. document your function so that the caller knows that it is responsible for freeing the memory, not your replace-function.

like image 114
Filip Roséen - refp Avatar answered Sep 28 '22 15:09

Filip Roséen - refp