none
none

Reputation: 183

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

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;
}

Upvotes: 0

Views: 809

Answers (1)

Mike Nakis
Mike Nakis

Reputation: 61969

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.

Upvotes: 1

Related Questions