Otros han respondido que malloc(0)
funciona. Responderé a una de las preguntas que usted solicitó y que aún no se contestaron (creo). La pregunta es sobre realloc(malloc(0), 0)
:
¿Qué devuelve malloc(0)
? ¿La respuesta sería la misma para realloc(malloc(0),0)
?
La norma dice esto acerca de realloc(ptr, size)
:
- si
ptr
es NULL
, se comporta como malloc(size)
,
- lo contrario (
ptr
no es NULL
), se desasigna el puntero del objeto de edad a por ptr
y devuelve un puntero a un nuevo búfer asignado. Pero si size
es 0, C89 dice que el efecto es equivalente a free(ptr)
. Curiosamente, no puedo encontrar esa afirmación en el borrador C99 (n1256 o n1336). En C89, el único valor razonable para devolver en ese caso sería NULL
.
Por lo tanto, hay dos casos:
malloc(0)
vuelve NULL
en una implementación. Entonces su llamada realloc()
es equivalente a realloc(NULL, 0)
.Eso es equivalente a malloc(0)
desde arriba (y eso es NULL
en este caso).
malloc(0)
devuelve no NULL
. Entonces, la llamada es equivalente a free(malloc(0))
. En este caso, malloc(0)
y realloc(malloc(0), 0)
son no equivalente.
en cuenta que hay un caso interesante aquí: en el segundo caso, cuando malloc(0)
devuelve no- NULL
en caso de éxito, todavía puede volver NULL
para indicar el fracaso. Esto dará como resultado una llamada como: realloc(NULL, 0)
, que sería equivalente a malloc(0)
, que puede o no devolver NULL
.
no estoy seguro de si la omisión en el C99 es un descuido o si significa que en C99, realloc(ptr, 0)
para no NULL
ptr
no es equivalente a free(ptr)
. Acabo de probar esto con gcc -std=c99
, y lo anterior es equivalente a free(ptr)
.
Edición: Creo que entiendo lo que su confusión es:
Veamos un fragmento de su código de ejemplo:
ptr = malloc(0);
if (ptr == realloc(ptr, 1024))
Lo anterior no es lo mismo que malloc(0) == realloc(malloc(0), 1024)
. En el segundo, la llamada malloc()
se realiza dos veces, mientras que en el primero, está pasando un puntero previamente asignado al realloc()
.
Analicemos primero el primer código. Suponiendo que malloc(0)
no devuelve NULL
en caso de éxito, ptr
tiene un valor válido. Cuando lo hace realloc(ptr, 1024)
, realloc()
básicamente le da un nuevo búfer que tiene el tamaño 1024, y el ptr
deja de ser válido. Una implementación conforme puede devolver la misma dirección que la que ya está en ptr
. Por lo tanto, su condición if
puede regresar verdadera. (Tenga en cuenta, sin embargo, mirando el valor de ptr
después de realloc(ptr, 1024)
puede ser un comportamiento indefinido.)
Ahora la pregunta que usted hace: malloc(0) == realloc(malloc(0), 1024)
. En este caso, supongamos que tanto el malloc(0)
en el LHS y RHS devuelve no NULL
. Entonces, están garantizados para ser diferentes. Además, el valor devuelto desde malloc()
en el LHS no ha sido free()
d todavía, por lo que cualquier otro malloc()
, calloc()
o realloc()
no puede devolver ese valor. Esto significa que si usted escribió su condición:
if (malloc(0) == realloc(malloc(0), 1024)
puts("possible");
no verá possible
en la salida (a menos que ambos malloc()
y realloc()
fallar y devolver NULL
).
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void *p1;
void *p2;
p1 = malloc(0);
p2 = realloc(p1, 1024);
if (p1 == p2)
puts("possible, OK");
/* Ignore the memory leaks */
if (malloc(0) == realloc(malloc(0), 1024))
puts("shouldn't happen, something is wrong");
return 0;
}
En OS X, mi código no generaba nada cuando lo ejecutaba. En Linux, imprime possible, OK
.
@ tommieb75: es útil haber respondido la pregunta original. Una vez dicho esto, esta pregunta tiene dos partes, y la segunda parte es más interesante y no es un engaño. Ver mi respuesta a esta pregunta para más detalles. –