Почему мне не нужно освобождать объекты кучи, когда я передаю их в функцию? - PullRequest
0 голосов
/ 17 сентября 2018

Следующая программа не имеет утечек памяти. Мой вопрос: почему str1 и str2 не нужно передавать в free (), даже если я malloc'd обе строки? Пожалуйста, обратите внимание на два прокомментированных места в коде, где я пытался освободить str1 и str2, раскомментирование этого кода привело к ошибке, говорящей о том, что я освободил объект без кучи. Но, насколько я понимаю, str1 и str2 являются объектами, созданными malloc, и, следовательно, объектами кучи. Я не понимаю этого противоречия.

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

1 Ответ

0 голосов
/ 17 сентября 2018

Конечно, вам нужно освобождать объекты кучи, независимо от того, передаете ли вы их функции или нет.Все, что возвращается malloc(), в конечном итоге должно быть free() d, независимо от того, как вы будете его использовать.

Ваша проблема заключается в следующем:

Следующая строка:

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

выделяет память для 4 символов и сохраняет ссылку на нее в str1.

Следующая строка:

str1 = "abc\n";

забывает любую память, на которую указывал str1 (что приводит к утечке памяти), и заставляет str1 указывать на новое местоположение в статических данных вашей программысегмент.Это память, которая никогда не выделялась и, следовательно, не может быть освобождена.

Чтобы решить вашу проблему, вместо установки str1 для указания "abc\n" необходимо использовать strcpy() для копирования "abc\n" выделенному блоку памяти, на который указывает str1.

Перед этим не забудьте увеличить 4 и 6 на 1, потому что строки в C также содержатзавершающий ноль байт, поэтому вам нужно выделить место для символов 5 и 7 соответственно.

...