В чем разница между освобождением указателя и присвоением ему значения NULL? - PullRequest
19 голосов
/ 12 марта 2010

Может кто-нибудь сказать мне разницу между:

int *p;
p=(int*)malloc(10*sizeof(int));
free(p);

или

int *p;
p=(int*)malloc(10*sizeof(int));
p=NULL;

Ответы [ 8 ]

39 голосов
/ 12 марта 2010

free освободит память, на которую указывает p - просто присвоить ее NULL не удастся (и, таким образом, у вас будет утечка памяти).

Стоит отметить, что рекомендуется указывать указатель на NULL ПОСЛЕ вызова free, так как это предотвратит случайное попытки доступа к освобожденной памяти (что все еще возможно, но обязательно не будет сделано).

9 голосов
/ 12 марта 2010

В C нет сборки мусора, поэтому, если вы явно не освободите кусок памяти, он никогда не освободится, даже если на него нет ссылок. Возможно, вы пришли из языков, которые собирают мусор, поэтому вам может быть трудно изменить образ мыслей, но всегда важно помнить, что нужно «вручную» освобождать все ресурсы на языках низкого уровня, таких как C.

Надеюсь, это поможет Приветствия

7 голосов
/ 12 марта 2010

p - указатель (на блок, динамически выделяемый в памяти ["в куче"])
Это означает, что p является переменной, которая содержит адрес в памяти определенного блока (или некоторого определенного размера, в примере блока, достаточно большого, чтобы содержать 10 целых чисел).

free(p); указывает логике управления памятью (среды выполнения C), что память, ранее занятая блоком, на который указывает p, может быть повторно использована.

p = NULL; устанавливает значение p в NULL (адрес, который он ранее содержал, потеряно), но блок в памяти, на который он также указывал, все еще считается используемым.

Может возникнуть некоторая путаница, потому что в таких языках, как Java, C #, Python и т. Д. Простое присвоение переменной NULL (или другому адресу в этом отношении) автоматически освободит основную память (при условии отсутствия других ссылок на этот адрес). существуют в других живых переменных).

Это не относится к C или C ++, что приводит к ошибкам, подобным следующему:

  free(p);
  // possibly some some code etc.
  // later:
  p[6] = 'a';  // <<---  Ouch we're modifying whatever new variable is there !!!

или

  // didn't call free(p)
  p = NULL;
  // now the memory allocated for p is held in memory even though it
  // is not going to be used (assuming no copies of p or of pointers to part
  // of that block were made.

В последнем случае расходуются только ресурсы, первый может привести к трудностям поиска ошибок.

Вот почему типичная идиома C :

   free(p);
   p = NULL;
2 голосов
/ 12 июля 2010

Лучший способ - сначала освободить память, а затем установить ее в NULL:

free(p);
p = NULL;
2 голосов
/ 12 марта 2010

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

1 голос
/ 25 июля 2017

p=NULL не освобождает память. Если вам больше не нужно использовать память, указанную p, вам следует использовать free(), иначе произойдет утечка памяти. Вам также следует установить p=NULL после вызова free(), чтобы избежать ошибочного доступа к этой памяти в будущем.

1 голос
/ 24 мая 2012

1.

int *p; p= (int * ) malloc(10*sizeof(int)); free(p);

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

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

не рекомендуется набирать указатель возврата в C

2

int *p; p=(int * )malloc(10*sizeof(int)); p=NULL;

Это может привести к утечке памяти : поскольку выделенная память здесь не освобождается. вы просто сбросили указатель на NULL.

1 голос
/ 13 марта 2010

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

Установка указателя на выделенную память в NULL не освобождает его.

Если вы используете реализацию, которая использует malloc на основе кучи, отлаживайте то, что выделяет, использует и освобождает память, и делайте то же самое с тем, что выделяет, использует и устанавливает указатель на память в NULL. *

Управление памятью зависит от реализации (см. http://en.wikipedia.org/wiki/Malloc#Implementations).

...