2009-07-02 10 views
39

pregunta muy sencilla, me hizo el siguiente programa:cero tamaño malloc

#include <stdlib.h> 
int main(int argc, char ** argv) 
{ 
    void * ptr; 
    ptr = malloc(0); 
    free(ptr); 
} 

Y no segfault en mi máquina. ¿Es un comportamiento portátil de stdlib malloc y gratis, o estoy buscando problemas?

Editar: Lo que parece no portátil es el valor devuelto por malloc. La pregunta es sobre la combinación malloc (0) + libre, no el valor de ptr.

+1

tener en cuenta que, si esto no funciona, no tendría que haber un montón de especial de los casos código. Las personas malloc una cantidad de bytes en función de una variable o expresión todo el tiempo, y sería incómodo tener que comprobar cero cada vez. –

+0

relacionado: http://stackoverflow.com/questions/2022335/whats-the-point-in-malloc0 – jldupont

+0

Lo sé: super último comentario en esta pregunta cerrada. Pero a veces hay un uso para 'malloc (0)' que no se menciona. En aquellas implementaciones en las que devuelve un valor no NULL, especialmente en una compilación DEBUG, es probable que asigne MÁS de lo que pidió y le da el puntero justo después de su encabezado interno. Esto le permite obtener un _feel_ de uso de memoria real si lo obtiene antes y después de una serie de asignaciones. –

Respuesta

54

El comportamiento es la implementación definida, recibirá un puntero NULL o una dirección. Llamando libre para el puntero recibido sin embargo, no debe causar ningún problema desde:

  • libre (NULL) está bien, no realiza ninguna operación
  • libre (dirección) está bien, si la dirección se recibió de malloc (u otras personas como calloc etc.)
23

Se permite devolver NULL, y está permitido devolver un puntero no nulo no se puede desreferenciar. Ambas formas son sancionados por la norma (7.20.3):

Si el tamaño del espacio solicitado es cero, el comportamiento es definido por la implementación: se devuelve ya sea un puntero nulo, o el comportamiento es tan si el tamaño fuera un valor distinto de cero, excepto que el puntero devuelto no se utilizará para acceder a un objeto.

+1

Esta no es exactamente la pregunta. No me importa el valor devuelto por malloc, pero sobre llamar gratis en un puntero devuelto por malloc (0). – shodanex

+2

Sigue siendo una muy buena respuesta porque, junto con la respuesta de Key, ofrece una descripción completa del comportamiento. – schnaader

3

Lo siento por el problema, debería haber leído las páginas man:

malloc() asigna size bytes y devuelve un puntero a la memoria asignada. La memoria no está borrada. Si el tamaño es 0, entonces malloc() devuelve NULL o un valor de puntero único que luego se puede pasar a free().

free() libera el espacio de memoria apuntado por ptr, que debe haber sido devuelto por una llamada previa a malloc(), calloc() o realloc(). De lo contrario, o si libre (ptr) ya se ha llamado antes, se produce un comportamiento indefinido. Si ptr es NULL, no se realiza ninguna operación.

Parece que es cierto al menos para el GNU libc

+4

RTFM :) http://en.wikipedia.org/wiki/RTFM –

1

actualizada teniendo en cuenta LIBT & los comentarios de Pax:

El comportamiento de llamar a malloc (0) depende de la realización o, en otras palabras, no portátil y undefined.

Link to CFaq pregunta para obtener más información.

+2

Los estándares ISO hacen una distinción muy clara entre definido, definido en implementación e indefinido. Tu también deberías. Definido por la implementación significa * is * defined pero el doco para esa implementación le dirá lo que hace. Indefinido significa que puede hacer * absolutamente cualquier cosa *, incluida, entre otras, la destrucción total del universo. – paxdiablo

+0

gracias por la aclaración (y el voto a la baja ;-)). Usé el término "indefinido" bastante flojo allí. Mi error. –

+0

No entiendes las preguntas frecuentes. no significa decir que el comportamiento general es la implementación definida. Significa que si el resultado es NULL o algún otro valor se define la implementación. Por ejemplo, un comportamiento válido no incluye el envío de un sigsegv. –

1

De acuerdo con el estándar

7.20.3 Si el tamaño del espacio solicitado es cero c, el comportamiento se define aplicación: se devuelve ya sea un puntero nulo, o el comportamiento es como si el tamaño fueron algunos valor distinto de cero, excepto que el puntero devuelto no se utilizará para acceder a un objeto.

-2

En mi experiencia, he visto que malloc (0) devuelve un puntero que puede liberarse. Pero, esto causa SIGSEGV en las declaraciones malloc() posteriores. Y esto fue altamente aleatorio.

Cuando agregué un cheque, para no llamar a malloc si el tamaño que se asignará es cero, me deshice de esto.

lo tanto, yo sugeriría que no se puede asignar memoria para el tamaño 0.

-Ashutosh