free () заменяет строку на ноль? - PullRequest
1 голос
/ 03 февраля 2012

Я мог бы немного помочь с free ().

Когда я запускаю следующее:

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

int main(int argc, const char *argv[])
{
    char *mystring = malloc(6 * sizeof(char));
    strcpy(mystring, "Hello");
    printf("%p\n", mystring);
    printf("%s\n", mystring);
    free(mystring);
    printf("%p\n", mystring);
    printf("%d\n", *mystring);

    return 0;
}

Я получаю:

0x8f46008
Hello
0x8f46008
0

Заменила ли free () строку «Hello» из памяти на ноль?

Примечание: это только для академических целей. Я бы никогда не сослался на свободную память по-настоящему.

Спасибо, Frank

Ответы [ 3 ]

6 голосов
/ 03 февраля 2012

Если у вас есть free d блок памяти, повторное чтение этой памяти приводит к неопределенному поведению и представляет серьезную угрозу безопасности и стабильности. Вы не можете рассчитывать на то, что значение true для памяти было free d, поэтому нет гарантии, будет ли память обнулена или нет. Если вы абсолютно не уверены в том, что делаете, не ссылаются на память после того, как вы ее освободили.

В качестве забавного анекдота об этом в оригинальной игре SimCity была ошибка, в которой она ссылалась на освобожденную память. В DOS это не привело к сбою, но когда оно было перенесено на Windows, игра начинала сбоить несколько раз. Команда Windows должна была специально встроить кейс в ОС, чтобы при запуске SimCity использовался специальный менеджер памяти для предотвращения такого рода сбоев. Вы можете прочитать полную историю здесь .

Короче, как только он освободится, не трогай его. В противном случае вы рискуете ошибками, которые некоторым бедным программистам в будущем придется исправить за вас. Такие инструменты, как valgrind, существуют для обнаружения ошибок такого рода именно потому, что они такие неприятные.

Надеюсь, это поможет!

2 голосов
/ 03 февраля 2012

Содержимое mystring (*mystring, mystring[0] и друзья) равно undefined после free памяти. Вы не можете полагаться на это, содержащее «Привет». Вы также не можете полагаться на него, содержащее ASCII NUL (как вы видите здесь).

Вы также не можете рассчитывать на то, что чтение не вызовет ошибки сегментации . Не делай этого .

Если вы запустите эту программу в средстве проверки памяти, например valgrind, вы увидите здесь ошибку о доступе к освобожденной памяти.

0 голосов
/ 03 февраля 2012

Может быть, в режиме отладки на вашем конкретном компьютере и скомпилирован с вашим конкретным компилятором, в целом, хотя вы должны ожидать, что этот кусок кода потерпит крах (или хуже).

...