2011-05-21 34 views
50

Duplicar posible:
Does free(ptr) where ptr is NULL corrupt memory?¿Es una buena práctica liberar un puntero NULL en C?

estoy escribiendo una función C que libera un puntero si era malloc() ed. El puntero puede ser NULL (en el caso de que se haya producido un error y el código no haya podido asignar nada) o asignado con malloc(). ¿Es seguro usar free(ptr); en lugar de if (ptr != NULL) free(ptr);?

gcc no se queja en absoluto, incluso con -Wall -Wextra -ansi -pedantic, pero ¿es una buena práctica?

+1

vea también: [comprobación de nula antes de llamar libre] (http://stackoverflow.com/questions/1912325/checking-for-null-before-calling-free) – Mat

+0

a abrirse. La pregunta era: *** "... es una buena práctica" ***; y no *: ... es legal "*. Son dos preguntas diferentes. Estoy interesado en saber la justificación para liberar un puntero NULL ya que no se puede liberar nada. En mi opinión, no tiene sentido y es un error del programa. – jww

Respuesta

107

Citando el estándar C, 7.20.3.2/2 de ISO-IEC 9899:

void free(void *ptr); 

Si ptr es un puntero nulo, no se produce la acción.

No marque NULL, solo agrega más código falso para leer y, por lo tanto, es una mala práctica.


Sin embargo, debe siempre cheque por NULL punteros cuando se utiliza malloc & co. En ese caso, NULL significa que algo salió mal, lo más probable es que no haya memoria disponible.

+0

Sí. Tengo una estructura que contiene punteros. Intento asignar cada uno de ellos.La primera vez que falla una asignación (el puntero devuelto por 'malloc()' es NULL), llamo a la función de desasignación, que pasa por todas ellas y libera las asignadas. Entonces señalo el error. ¿Hay alguna forma mejor de hacer esto? – rid

+0

@rdineiu, suponiendo que inicialice los punteros para anular antes de las llamadas 'malloc' (para que nunca' libre' un puntero no inicializado), esa es exactamente la manera correcta de hacerlo. –

+3

Algunas respuestas en este enlace de StackOverflow: http://stackoverflow.com/questions/1938735/does-freeptr-where-ptr-is-null-corrupt-memory mencionan que ciertas bibliotecas C ignoran este estándar y arrojan errores, a pesar de lo que dice el estándar C Puede valer la pena mirar. –

5

vueltas al azar googlear hasta http://linux.die.net/man/3/free que establece:

Si ptr es NULL, se lleva a cabo ninguna operación.

+2

Tiene razón, pero el sitio que lo vinculó no es muy confiable como referencia. Tiene errores importantes en su documentación de varias funciones principales de C. –

+1

(espero que esto lo notifique) ¿Mejor? – Hello71

4

En mi opinión, no, al menos no en su caso.

Si no pudo asignar memoria, debería haber verificado esa MANERA antes de la llamada de forma gratuita.

+2

+1 para el segundo párrafo. –

+0

Estoy revisando mucho antes. Tengo una estructura que contiene punteros. Intento asignar cada puntero. Si en algún momento una de las asignaciones falla, invoco la función de desasignación que recorre cada puntero y la libera. ¿Hay alguna forma mejor de hacer esto? – rid

17

Es una buena práctica no molestarse en buscar NULL antes de llamar al free. La comprobación solo agrega desorden innecesario a su código, y free(NULL) está garantizado para ser seguro. Desde la sección 7.20.3.2/2 de la norma C99:

La función libre hace que el espacio apuntado por ptr a cancelar la asignación, es decir, hecha disponibles para su posterior distribución. Si ptr es un puntero nulo, no se produce ninguna acción.

+0

¿Qué pasa si la llamada a 'free' tiene sobrecarga. ¿No sería más eficiente evitar la llamada? – jww

+0

@jww Podría ser, pero debes preguntarte si la compensación vale la pena. El caso * común * es que las cosas no fallan y que probablemente termines con memoria asignada en lugar de punteros nulos. Si agrega cheques de puntero nulo en todas partes, esto significa que ahora ha impactado negativamente el rendimiento de sus casos comunes (y ha añadido desorden a su código) solo para evitar una llamada de función extra en lo que probablemente sea un caso de falla atípica. – jamesdlin

+0

@jww La tara no es lógicamente más que 'if (ptr == NULL) return; ' ¡así que todo lo que puede esperar lograr al controlarse es duplicar la sobrecarga! – Persixty

Cuestiones relacionadas