Что происходит с памятью после free()?

Я знаю, что на вашем жестком диске, если вы удалите файл, данные не исчезнут (мгновенно). Данные сохраняются до тех пор, пока не будут перезаписаны. Мне было интересно, существовало ли подобное понятие в памяти. Скажем, я выделяю 256 байт для строки, эта строка все еще плавает где-то в памяти после того, как я ее free() до тех пор, пока она не будет перезаписана?


person Lienau    schedule 26.02.2011    source источник
comment
Какое это имеет отношение к окнам? Вы конкретно про окна спрашиваете?   -  person UpAndAdam    schedule 05.09.2013


Ответы (4)


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

person Jeremiah Willcock    schedule 26.02.2011
comment
Это то, что я думаю, я должен использовать ZeroMemory, прежде чем я free() его, чтобы предотвратить его чтение после освобождения. Спасибо. - person Lienau; 26.02.2011
comment
@Lienau Если вы хотите немного излишеств (всегда хорошо :)), вы можете использовать DoD или Gutmann, но они предназначены для вашего жесткого диска ... - person Mateen Ulhaq; 26.02.2011

Ваша аналогия верна. Данные в памяти не исчезают или что-то в этом роде; значения действительно могут быть там после free(), хотя попытка чтения из освобожденной памяти является поведением undefined.

person chrisaycock    schedule 26.02.2011

Ответ сильно зависит от реализации. В хорошей реализации вполне вероятно, что по крайней мере начало (или конец?) памяти будет перезаписано бухгалтерской информацией для отслеживания свободных участков памяти, которые впоследствии можно будет использовать повторно. Однако детали будут различаться. Если ваша программа имеет какой-либо уровень параллелизма/потоков (даже в библиотечной реализации, которую вы можете не увидеть), то такая память может затираться асинхронно, возможно, даже таким образом, что даже чтение ее опасно. И, конечно же, реализация free может полностью удалить диапазон адресов из виртуального адресного пространства программы, и в этом случае попытка сделать что-либо с ним приведет к сбою вашей программы.

С точки зрения автора приложения вы должны просто обращаться с free в соответствии со спецификацией и никогда не обращаться к освобожденной памяти. Но с точки зрения системного разработчика или интегратора может быть полезно знать (или спроектировать) реализацию, и в этом случае ваш вопрос будет интересен.

person R.. GitHub STOP HELPING ICE    schedule 26.02.2011
comment
У меня действительно нет намерения читать мою освобожденную память, поскольку я думал то же самое о неопределенности и нестабильности. Вопрос чисто из любопытства. - person Lienau; 26.02.2011

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

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

/* The number of memory bytes to test */
#define MEM_TEST_SIZE 256

void outputMem(unsigned char *mem, int length)
{
    int i;

    for (i = 0; i < length; i++) {
        printf("[%02d]", mem[i] );
    }   
}

int bytesChanged(unsigned char *mem, int length)
{
    int i;
    int count = 0;

    for (i = 0; i < MEM_TEST_SIZE; i++) {
        if (mem[i] != i % 256)
            count++;
    }
    return count;
}

main(void)
{
    int i;
    unsigned char *mem = (unsigned char *)malloc(MEM_TEST_SIZE);

    /* Fill memory with bytes */
    for (i = 0; i < MEM_TEST_SIZE; i++) {
        mem[i] = i % 256;
    }

    printf("After malloc and copy to new mem location\n");
    printf("mem = %ld\n", mem );
    printf("Contents of mem: ");
    outputMem(mem, MEM_TEST_SIZE);

    free(mem);
    printf("\n\nAfter free()\n");
    printf("mem = %ld\n", mem );
    printf("Bytes changed in memory = %d\n", bytesChanged(mem, MEM_TEST_SIZE) );
    printf("Contents of mem: ");
    outputMem(mem, MEM_TEST_SIZE);


}
person Lawrence Woodman    schedule 26.02.2011