C: что realloc делает с памятью, которую он освобождает?

#c

#c

Вопрос:

У меня есть игрушечная программа на C, которая использует malloc и realloc для выделения, а затем освобождения памяти:

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

int main()
{
    int *ptr, i , n1, n2;
    printf("Enter size: ");
    scanf("%d", amp;n1);

    ptr = (int*) malloc(n1 * sizeof(int));

    printf("Addresses of previously allocated memory: ");
    for(i = 0; i < n1;   i)
         printf("%pn",ptr   i);

    printf("nEnter the new size: ");
    scanf("%d", amp;n2);

    // rellocating the memory
    ptr = realloc(ptr, n2 * sizeof(int));

    printf("Addresses of newly allocated memory: ");
    for(i = 0; i < n2;   i)
         printf("%pn", ptr   i);
  
    printf("%dn", *(ptr   n2   1));

    free(ptr);

    return 0;
}
  

Он принимает размер, n1 который он выделяет, а затем размер n2 , который он перераспределяет. Эта программа также, предполагая n1 > n2 , выводит значение at ptr n2 1 просто для того, чтобы посмотреть, на что настроена освобожденная память.

На моем Mac, используя cc , значение, которое я получаю обратно, printf("%dn", *(ptr n2 1)); равно 0 .

Это зависит от компилятора? Всегда ли realloc устанавливает память, которую он больше не использует, в 0 после перераспределения?

Комментарии:

1. Он делает то же самое free() — освобождает ее для повторного использования. Попытка получить доступ к значению по адресу после его освобождения является неопределенным поведением .

2. когда он это делает, устанавливает ли он значения в 0?

3. Некоторые реализации malloc() имеют возможность «отравлять» (например, заполнять ее шаблоном типа 0xdeadbeef ) память, освобожденную с помощью free() или realloc(), чтобы помочь отлаживать ошибки, связанные с использованием после освобождения.

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

Ответ №1:

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

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

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