#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 хранят свои собственные данные бухгалтерского учета в освобожденных блоках, и может случиться так, что данные бухгалтерского учета, хранящиеся в этом месте, просто случайно оказываются равными нулю в этой конкретной ситуации. Но систематическое обнуление освобожденной памяти (которая будет повторно использоваться процессом) обычно было бы пустой тратой циклов процессора, поскольку код пользователя не должен снова обращаться к этой памяти, поэтому обычно это не выполняется.
На самом деле, теперь, когда я смотрю на ваш код, вы никогда ничего не записывали в свой выделенный блок. Так что очень возможно, что он все время содержал нули. Обычно память, недавно выделенная ОС, обнуляется (что гарантирует, что она не содержит конфиденциальных данных из других процессов), и поэтому выделенная память иногда будет обнуляться, если она поступила непосредственно из ОС, а не из ранее освобожденного блока.