Правильный способ освободить память - PullRequest
3 голосов
/ 12 мая 2011

Прошло немного времени, так как я сделал немного C, и мне нужно освежить мое понимание указателей. Вот функция, которая изменяет содержимое указателя. Вопрос в том, правильный ли этот код. Достаточно ли этого, если я освобождаю только указатель, или мне нужно освободить содержимое по указателю

void foo(char **str) {
   // str has been allocated enough bytes for the following text
   *str = "allocate some text";
}

int main(int arc, char *argv[]) {
    char *someString;
    foo(&someString);
    free(someString); // is this the correct place to free
}

Спасибо.

Ответы [ 5 ]

10 голосов
/ 12 мая 2011

Нет, вы не хотите звонить free(), потому что вы никогда не malloc() вводили данные. Более конкретно, вызов free() для указателя на строковый литерал приводит к неопределенному поведению .

2 голосов
/ 12 мая 2011

В этом случае вы вообще не должны освобождаться free() всегда должно соответствовать вызову функции malloc().

Здесь вы «освобождаете» постоянную память, которая никогда не выделялась.

1 голос
/ 12 мая 2011

Вы не показываете в своем коде, но вы пишете, что str был выделен с достаточным количеством байтов.Так что это нормально, и может быть free ed, но затем вы назначаете указатель на константную строку для str - *str = "allocate some text"; (и, как сказал Оли, вызывает неопределенное поведение на свободном), вместо этого выполните strcpy():

strcpy(str, "allocate some text");
1 голос
/ 12 мая 2011

В этом коде меня что-то озадачивает.

Почему в комментарии говорится "str выделено достаточно байтов для следующего текста"?Даже если он был выделен, вы присваиваете указателю новое значение, поэтому он ничего не покупает, выделив эту память.

В любом случае, согласно этому коду, free() не должен называться.

0 голосов
/ 12 мая 2011

Сначала необходимо отрегулировать вызов метода foo, поскольку параметры не совпадают. Это должно выглядеть примерно так:

foo(&someString);

Но лично я бы согласился на то место, где вы назвали метод free(someString). Потому что приложение заканчивается и вам больше не нужен указатель.

...