Вместо того, чтобы просто использовать free () и иметь указатель, указывающий на какой-то новый блок, как действительно очистить ранее указанный блок памяти? - PullRequest
0 голосов
/ 14 сентября 2011

Я пытаюсь освободить динамически выделяемую память с помощью free (), но я обнаружил, что он делает так, чтобы указатель аргумента указывал на какое-то новое местоположение, и оставлял ранее указанное место в том виде, в каком он былне очищаетсяИ если я снова использую malloc, указатель может указывать на этот грязный блок, и он уже заполнен мусором, который действительно раздражает ..

Я немного новичок в C, и я думаю delete [] в c ++не имеет этой проблемыЛюбой совет?

Спасибо

Ответы [ 3 ]

6 голосов
/ 14 сентября 2011

По free память только что освобождена от использования.Это освобождено от того, чтобы быть выделенным вам.это явно не очищается.Некоторое старое содержимое может присутствовать в этих местах памяти.Чтобы избежать этого, есть два решения.

Решение 1:

Вам нужно будет сделать memset после выделения памяти, используя malloc.

Пример кода:

unsigned int len = 20; // len is the length of boo
char* bar = 0;
bar= (char *)malloc(len);

memset(bar, 0, len);

Решение 2:

Или используйте calloc(), который по умолчанию инициализирует память до 0.

КодПример:

  int *pData = 0;
  int i = 10;
  pData = (int*) calloc (i,sizeof(int));

Я думаю, что delete[] в c ++ не имеет этой проблемы.

Нет
Он ведет себя точнотаким же образом.Если вы явно не установите указатель на 0, указатель delete не будет указывать на 0.Поэтому всегда устанавливайте указатель на 0 после его удаления.


Когда следует использовать malloc сверх calloc или наоборот?

Поскольку calloc устанавливаетвыделенная память для 0 это может занять немного времени, поэтому вы, возможно, захотите использовать malloc(), если эта производительность вызывает проблемы.

Если инициализация памяти более важна, используйте calloc(), поскольку она делает это явно для вас.

Кроме того, некоторые ОС, такие как Linux, имеют модель памяти Lazy Allocation , в которой возвращаетсяадрес памяти является виртуальным адресом, и фактическое выделение происходит только во время выполнения.ОС предполагает, что она сможет обеспечить это распределение во время выполнения.

Память, выделенная malloc, не поддерживается реальной памятью до тех пор, пока программа не коснется ее.

Покатак как calloc инициализирует память на 0, вы можете быть уверены, что ОС уже поддержала выделение с фактической оперативной памятью (или подкачкой).


Как насчет realloc?

Да, поведение, аналогичное malloc.
Выдержка из документации :

void * realloc ( void * ptr, size_t size );

Перераспределить блок памяти

Размер блока памяти, на который указывает параметр ptr, изменяется на размер в байтах, увеличивая или уменьшая объем памятидоступны в блоке.

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

В случае, если ptr равен NULL, функция ведет себя точно так же, как malloc, присваивая новый блок байтов размера и возвращая указатель на его начало.

В случае, если размер равен 0,память, ранее выделенная в ptr, освобождается, как если бы был сделан вызов free, и возвращается указатель NULL.

1 голос
/ 14 сентября 2011

Вы можете использовать calloc( ) вместо malloc( ), чтобы очистить выделенную память до нуля.

0 голосов
/ 14 сентября 2011

Почему вновь выделенная память, заполненная мусором, "действительно раздражает"?Если вы выделяете память, вероятно, это потому, что вы собираетесь использовать ее для чего-то - что означает, что вы должны сохранить какое-то значимое значение в ней до того, как попытается прочитать ее.В большинстве случаев в хорошо написанном коде нет причин заботиться о том, что находится во вновь выделенной памяти.

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

И free() не «указывает указатель аргумента на какое-то новое местоположение».free(ptr) делает память, на которую указывает ptr, доступной для будущего распределения.Он не изменяет содержимое объекта-указателя ptr (хотя адрес, сохраненный в ptr, становится недействительным).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...