user3186023
user3186023

Reputation:

strdup() causing memory leaks?

I've implemented a function that returns a string. It takes an integer as a parameter (age), and returns a formatted string.

All is working well, except from the fact that I have some crazy memory leaks. I know strdup() is the cause of this, but I've tried to research some fixes to no avail.

My code is:

const char * returnName(int age) {

    char string[30];

    sprintf( string, "You are %d years old", age);

    return strdup(string);
}

Valgrind's output is:

==15414== LEAK SUMMARY:
==15414==    definitely lost: 6,192 bytes in 516 blocks
==15414==    indirectly lost: 0 bytes in 0 blocks
==15414==      possibly lost: 0 bytes in 0 blocks
==15414==    still reachable: 0 bytes in 0 blocks
==15414==         suppressed: 0 bytes in 0 blocks

Any help in resolving this memory leak issue is greatly appreciated.

Upvotes: 1

Views: 6690

Answers (5)

cadaniluk
cadaniluk

Reputation: 15229

From man strdup:

Memory for the new string is obtained with malloc(3), and can be freed with free(3).

So you need to free the space allocated and returned by strdup.

Say you invoke returnName like that:

 const char* str = returnName(3);

After you're done with str you can free it like this:

free((char*) str);

The cast is needed because free expects a non-const void*. This explicit conversion is alright here because returnName actually should return constant data1. Calling free is only a nasty implementation detail here.


1 As discussed with @M.M in the comments to this answer.

Upvotes: 3

Forhad Hossain
Forhad Hossain

Reputation: 438

const char * returnName(int age) {
    char string[30];
    sprintf( string, "You are %d years old", age);
    return strdup(string);
}

return type of returnName() is const char*. So, you can not hold the returned value to a char* type variable. Hold returned value to a const char* variable and cast it to char* while make memory free

const char* retName = returnName(3);
// Use retName
free((char*)retName);

Upvotes: 1

PC Luddite
PC Luddite

Reputation: 6098

strdup() is essentially equivalent to

char* dup = malloc(strlen(original) + 1);
strcpy(dup, original);

So you need to remember to call free() after you're finished using the string.

const char* name = returnName(20);
/* do stuff with name */
free((void*)name);

If you don't call free(), then of course valgrind reports a leak.

Upvotes: 5

Michi
Michi

Reputation: 5297

strdup looks something like this:

char *strdup(const char *str){
    size_t n = strlen(str) + 1;
    char *dup = malloc(n);

    if(dup){
        strcpy(dup, str);
    }

    return dup;
}

As you can see there is malloc involved too, which means that at some point after you dynamically allocate that memory using strdup you have to free it after you don't need it any more.

Upvotes: 3

user3629249
user3629249

Reputation: 16540

the cause of the memory leaks is NOT from the call to strdup() but rather because the caller of the posted function is failing to pass the returned pointer to free() when done with the string.

Upvotes: 1

Related Questions