2010-03-01 27 views
33

¿Qué sucede dentro de la memoria si intentamos liberar un puntero que apunta a NULL? ¿Es eso alguna vez válido?liberando un puntero nulo

¿Por qué no muestra ningún mensaje de advertencia/error?

+0

nada; ... aún así, el comportamiento de liberar un puntero que no sea nulo, nada que no haya sido maltratado anteriormente, es indefinido y generalmente desastroso. –

+9

Los punteros no están "apuntando a NULL". Los punteros ya sea * are * o * no son * null. "Puntero que apunta a NULL" es una afirmación sin sentido. – AnT

+0

si un puntero almacena una dirección de un varibale, es una práctica habitual que un programador diga puntero apuntando a esa variable. Por lo tanto, no es una afirmación sin sentido. Puede que esté equivocado. Pero no me parece como una declaración no sensorial. – Vijay

Respuesta

51

Desde sección C99 7.20.3.2: La función libre

Sinopsis

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

Descripción

2 La función libre hace que el espacio apuntado por ptr ser desasignado, es decir, hecho disponibles para una mayor asignación. Si ptr es un puntero nulo, no se produce ninguna acción.

+11

¿Por qué un voto a favor? –

15

De http://linux.die.net/man/3/malloc:

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

+10

Para aquellos que temen que sea una extensión de Linux, ese comportamiento es obligatorio según el estándar C90. – AProgrammer

+0

Es interesante observar que las personas que escribieron esa página del manual de Linux no entendieron o no les interesó la diferencia entre 'NULL' y el" valor del puntero nulo ". La mayoría de los documentos serios y/o formales normalmente son bastante pedantes al respecto (ver otras respuestas). – AnT

3

¿Qué ocurre dentro de la memoria si tratamos para liberar un puntero que está apuntando a NULL. es eso alguna vez valido?

Nada.

¿por qué no muestra ningún mensaje de advertencia/error ?

En primer lugar, el comportamiento es válido por definición, por lo que no es necesario emitir ningún error o advertencia.

En segundo lugar, un puntero apunta a NULL en tiempo de ejecución. ¿Cómo debería mostrarse un mensaje de advertencia o error, si es que aparece? Imagina que estás jugando a un juego llamado Kill the Zombie y mientras dos de estos seres te están atacando, aparece un mensaje de error emergente que dice: "Advertencia, puntero NULL liberado".

+0

¿Cuál es su punto allí? El ejemplo me recuerda desde Windows y no tiene nada que ver con los mensajes de error de registro. La decisión sensata de las advertencias es enviarlas a stderr. – Cheery

+3

Mi punto fue expresado claramente. La "advertencia" (solo es útil para el programador) interferiría con la salida del programa normal. –

+0

Oh, él preguntó por qué no * muestra *. :) Mi error. Es una pregunta extraña, casi nada en C muestra advertencias o errores sin que el programador verifique errores. – Cheery

0

Podría ser seguro (no lo sabía, pero las otras respuestas parecen sugerir eso), pero no caeré en el hábito de no preocuparme si el puntero ya es nulo. La asignación p = NULL; después de cada libre pronto sigue como un corolario. Esto es peligroso en aplicaciones multiproceso, ya que después de esta asignación, p podría ser utilizado por otro hilo y sería liberado nuevamente por el hilo actual mientras se espera que esté vivo por los otros hilos.

Cada memoria malloc'd debe liberarse una vez. Período.

+0

El acceso a los datos compartidos en aplicaciones multiproceso debe protegerse, lo que evitará la pérdida de memoria que describa. – outis

+0

@outis El problema no es la pérdida de memoria, sino que la eliminación de datos que los otros hilos esperan está viva (probablemente dará como resultado un error de segmentación). El acceso protegido no es suficiente en este caso. –

+0

Lo que menciona sobre el enhebrado parece correcto, pero, por lo que yo sé, no se aplica a esta pregunta y no intenta responder a esta pregunta. –

6

liberar el puntero nulo no tendrá ningún efecto en la ejecución.

4

me gustaría ir para:

#ifdef MY_DOUBTS_HAUNT_ME_IN_MY_DREAMS 
    #define safe_free(x) do { if ((x)) free((x)); } while(0) 
#elseif /* feeling gutsy */ 
    #define safe_free(x) free((x)) 
#endif 

; - ||

+0

en primer lugar, probablemente quieras decir "safe_free". pero cuál sería el objetivo de esto. 'free (NULL)' es perfectamente legal. No tiene sentido comprobar 'NULL' antes de' free'ing. –

+1

¿No puedes reconocer una broma (incluso cuando está mal escrita)? –

+1

Bromas aparte, el servidor Kamailio-SIP http://www.kamailio.org/, con advertencias habilitadas, registra una advertencia cuando libera (0). –

5

Erase hace mucho tiempo, hubo implementaciones de 'libre()' que se estrelló cuando se les da un puntero nulo para liberar. Esto solo se aplica a las implementaciones anteriores a la norma C89 (C90) que no se han modificado para tratar el problema desde entonces.

En mi experiencia, hay esencialmente ninguna de esas implementaciones izquierda (y tampoco debe haber), por lo que ahora es seguro para liberar punteros nulos.

Si usted tiene cualquier requisito de portar a sistemas extremadamente raros y antiguos, entonces tal vez debería seguir siendo cauteloso. Por otro lado, si tuviera que preocuparse de tales sistemas, probablemente sabría sobre el tema (y una gran cantidad de otros problemas), o habría algún conocimiento común en torno al código que lo indique.

Cuestiones relacionadas