Why don't I have to free heap objects when I pass them into a function?

3391 views c
0

The following program has no memory leaks. My question is, why does str1 and str2 not have to be passed into free(), even though I malloc'd both strings? Please see two commented locations in the code where I attempted to free str1 and str2, uncommenting that code resulted in an error saying I free'd a non-heap object. But from my understanding, str1 and str2 are objects created by malloc, hence are heap objects. I do not understand this contradiction.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* StrCat(char* s1, const char* s2) {
    // Removing const from const char* s2
    //  made no difference on memory leak error message
    char *s, *tmp;
    s = tmp = malloc(strlen(s1) + strlen(s2) + 1);
    strcpy(tmp, s1);
    tmp += strlen(s1);
    strcpy(tmp, s2);
    //free(str1); free(str2); Why not?
    printf("%d\n", s[strlen(s)] == '\0'); // Prints 1
    return s;
}

int main(int argc, char** argv) {
    char* str1 = malloc(4 * sizeof (char));
    str1 = "abc\n";
    char* str2 = malloc(6 * sizeof (char));
    str2 = "party\n";

    char* new = StrCat(str1, str2);
    //free(str1); free(str2); Why not?
    printf("%s\n", new);
    free(new); // Required
    return 0;
}

answered question

You may be lucky that the compiler spots that you throw away what malloc() returns in the main() function and optimizes away the call to malloc(), so you don't actually have any allocated memory to leak. But in general, you need to free allocated memory. Did you use Valgrind to check for memory leaks?

1 Answer

12

Of course you need to free heap objects, whether you pass them to a function or not. Whatever is returned by malloc() must eventually be free()d, regardless of how you will use it.

Your problem is as follows:

The following line:

char* str1 = malloc(4 * sizeof (char));

allocates memory for 4 characters and stores a reference to it in str1.

The following line:

str1 = "abc\n";

forgets whatever memory str1 was pointing to, (thus causing a memory leak,) and makes str1 point to a new location, in your program's static data segment. This is memory which was never allocated, and therefore may not be freed.

In order to solve your problem, instead of setting str1 to point to "abc\n" you need to use strcpy() to copy "abc\n" to the allocated memory block which is pointed by str1.

Before doing that, do not forget to increment your 4 and your 6 by 1 each, because strings in C also contain a null-terminating byte, so you need to allocate space for 5 and 7 characters respectively.

posted this

Have an answer?

JD

Please login first before posting an answer.