¿Free (ptr) donde ptr es NULL corrompe la memoria?


Teóricamente puedo decir que

free(ptr);
free(ptr); 

Es una corrupción de la memoria ya que estamos liberando la memoria que ya ha sido liberada.

Pero ¿qué pasa si

free(ptr);
ptr=NULL;
free(ptr); 

Como el sistema operativo se comportará de una manera indefinida, no puedo obtener un análisis teórico real para esto sobre lo que está sucediendo. Lo que sea que esté haciendo, ¿es esta corrupción de memoria o no?

¿Es válido liberar un puntero NULO?

Author: Prasoon Saurav, 2009-12-21

10 answers

7.20.3.2 La función free

Sinopsis

#include <stdlib.h> 
void free(void *ptr); 

Descripción

La función free hace que el espacio apuntado por ptr sea desasignado, es decir, hecho disponible para su posterior asignación. Si ptr es un puntero nulo, no se produce ninguna acción.

Véase ISO-IEC 9899.

Dicho esto, al mirar diferentes bases de código en la naturaleza, notarás que la gente a veces lo hace:

if (ptr)
  free(ptr);

Esto es porque algunos C los tiempos de ejecución (seguramente recuerdo que era el caso en PalmOS) se bloqueaban al liberar un puntero NULL.

Pero hoy en día, creo que es seguro asumir free(NULL) es un nop según las instrucciones del estándar.

 193
Author: Gregory Pakosz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-24 13:41:49

Todas las versiones compatibles con los estándares de la biblioteca C tratan a free (NULL) como un no-op.

Dicho esto, en un momento hubo algunas versiones de free que se bloquearían en free (NULL), por lo que es posible que vea algunas técnicas de programación defensivas recomendadas:

if (ptr != NULL)
    free(ptr);
 19
Author: R Samuel Klatchko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-21 08:02:07

Si ptr es NULL, no se realiza ninguna operación.

Dice la documentación.

 10
Author: Michael Krelin - hacker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-21 07:46:52

Recuerdo haber trabajado en PalmOS donde free(NULL) se estrelló.

 10
Author: jlru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-27 12:43:12
free(ptr);
ptr=NULL;
free(ptr);/*This is perfectly safe */

Puede eliminar de forma segura un puntero NULO. No se realizará ninguna operación en ese case.In otras palabras free () no hace nada sobre un puntero NULO.

 8
Author: Prasoon Saurav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-21 07:53:09

Uso recomendado:

free(ptr);
ptr = NULL;

Véase:

man free

     The free() function deallocates the memory allocation pointed to by ptr.
     If ptr is a NULL pointer, no operation is performed.

Cuando configura el puntero a NULL después de free(), puede llamar a free() nuevamente y no se realizará ninguna operación.

 8
Author: stefanB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-21 08:38:41

free(NULL) es perfectamente legal en C, así como delete (void *)0 y delete[] (void *)0 son legales en C++.

POR cierto, liberar memoria dos veces generalmente causa algún tipo de error de tiempo de ejecución, por lo que no daña nada.

 6
Author: n0rd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-21 07:55:18

Free(ptr) es save en C si ptr es NULL, sin embargo, lo que la mayoría de la gente no sabe es que NULL no necesita ser igual a 0. Tengo un buen ejemplo de la vieja escuela: En el C64, en la dirección 0, hay un puerto IO. Si escribiera un programa en C accediendo a este puerto, necesitaría un puntero cuyo valor sea 0. La biblioteca c correspondiente tendría que distinguir entre 0 y NULL entonces.

Saludos cordiales

 2
Author: andi8086,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-19 08:39:06

No la corrupción de memoria, pero el comportamiento depende de la implementación. Por norma, debería ser un código legal.

 0
Author: Pavel Radzivilovsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-21 07:45:08

Ptr está apuntando a alguna ubicación de memoria, digamos 0x100.

Cuando libera(ptr), básicamente está permitiendo que 0x100 sea utilizado por el administrador de memoria para ser utilizado para otra actividad o proceso y en palabras simples es la desasignación de recursos.

Cuando haces ptr=NULL, estás haciendo que ptr apunte a una nueva ubicación(no nos preocupemos por lo que es NULL). Al hacer esto, perdió la pista de los datos de memoria 0x100.Esto es lo que es la pérdida de memoria.

Así que no es recomendable usar ptr = NULL en un válido ptr.

En su lugar, podría hacer una comprobación segura usando:

If (ptr != NULO) {free (ptr);}

Cuando libera (ptr) donde ptr ya está apuntando a NULL, realiza no operation.So, es seguro hacerlo.

 -1
Author: kishanp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-10 14:15:29