2011-03-21 15 views
5

intentado el siguiente código:entendimiento concepto de libre

#include<stdio.h> 
int main() 
{   
     int *p,*q; 
     p = (int *)malloc(sizeof(int)); 
     *p =10; 
     q = p; 
     printf("%u \n",p); 
     printf("%u \n",q); 
     free(p); 
     printf("%u \n",p); 
     return 0; 
} 

La salida tiene es el siguiente:

[[email protected] Tazim]# ./a.out 
154804232 
154804232 
154804232 

¿Por qué es que la dirección en el interior p está siendo impresa, incluso si he hecho free(p);? ¿Qué ha hecho free(p) entonces?

Quiero entender claramente el concepto de libre/malloc. Cualquier ayuda será valiosa.

Respuesta

5

free() solo libera la memoria en el montón. No cambia el valor de su puntero. Si trataste de imprimir la memoria apuntada por tu puntero, vas a probablemente y obtengas algún tipo de basura.

Además, cuando llamó free, que le dieron el puntero, no la dirección para el puntero, por lo free no puede cambiar el puntero ...

+0

Eso es cierto, pero imprimir el valor del puntero sigue siendo un comportamiento indefinido - http://stackoverflow.com/q/4076563/57428 – sharptooth

+0

@sharptooth - Gracias. No sabía que – MByD

3

Eso es un comportamiento indefinido - una vez que haya free d el puntero de la dirección almacenada se convierte en válido y can't do anything with it - no sólo no se puede eliminar la referencia, pero no se puede incluso printf() el valor del puntero.

+0

Esto técnicamente no responde la pregunta. –

+0

@JUST MI OPINIÓN correcta: Sí, una vez que haya hecho 'free()' no puede imprimir la dirección, puede producir cualquier resultado. – sharptooth

+0

La pregunta era "¿Por qué esa dirección dentro de p sigue imprimiéndose incluso si he hecho gratis (p); ¿Qué tiene (p) hecho gratis? Quiere entender claramente el concepto de libre/malloc". Usted no respondió ninguna parte de eso. –

2

Está imprimiendo los punteros, es decir, la dirección de la zonas de memoria asignadas para ti. Liberar una zona de memoria con free no establece la dirección del puntero a 0x00 como creo que espera.

Le dice al sistema operativo que la zona de memoria está disponible de nuevo para su futura reutilización.

Si estaba imprimiendo *p después de free(p), tendría problemas.

+0

Debe editar su respuesta y eliminar "Imprimir p está bien ..." ya que es un comportamiento indefinido. – Jens

+0

Simplemente lo hice, gracias. – Sylvain

0

Recuerde: un puntero no es más que una dirección. Antes, después de tu malloc, o gratis, te dará el mismo resultado. Lo único que malloc() hace es reservar espacio en esta dirección. Lo único que hace libre es liberarlo (lo más probable es que marque esta dirección como utilizable para almacenar otras cosas, "limpiarla" llevaría mucho tiempo). Es por eso que poner su puntero a NULL después de una gratis es una buena idea; porque puede estar seguro si el puntero está conectado a algo o no.

+0

'malloc()' no almacena nada en la dirección que devuelve. –

+0

Err ... tal vez es mi inglés el que está podrido. ¿Qué diferencia harías entre "almacenar" y "reservar espacio"? – Raveline

+0

Reservar espacio significa decirle al sistema de gestión de memoria "no le dé esta memoria a nadie más". Almacenar significaría realmente poner algún valor en ese espacio. –

1

malloc() y su ilk reserva espacio en un área de almacenamiento de memoria llamada el "montón" y devuelve un puntero a esa área reservada. Por lo tanto, en su muestra anterior, p se le da un puntero a, probablemente, una región de memoria de cuatro bytes que se ha reservado para su uso (cuya dirección es 154804232 esta vez). Cuando haga *p = 10, ahora está colocando el valor entero 10 en la memoria apuntada. Cuando hace q = p, ahora está haciendo q apuntando al mismo fragmento de memoria del montón guardado.

free() y su tipo solo unreserve la memoria. Cuando llamas al free() estás diciendo "ya no voy a usar esta memoria". Todo lo que free() hace es decirle al sistema de gestión de memoria que el bloque de memoria está ahora disponible para su uso una vez más. Enfáticamente, no cambie su puntero. Simplemente indica que el bloque de memoria está disponible.Después de eso, depende de usted asegurarse de no volver a utilizar ese puntero.

Si utiliza ese puntero nuevamente, puede funcionar bien. Una vez. O dos veces O mil veces. Funcionará bien, básicamente, hasta que lo use después de que alguien más afirme que el bloqueo de memoria que ha dicho es gratuito y hace algo al respecto. Cuando eso sucede, Suceden cosas malas < tm>. Por favor, no hagas que sucedan cosas malas.

0

free does not reassign the pointer para señalar a algo más. De hecho, el estándar C no menciona nada con el puntero. Esto es todo lo que dice en la descripción:

La función libre hace que el espacio apuntado por ptr ser desasignado, que es, puestos a disposición para su posterior asignación . Si ptr es un puntero nulo, no ocurre ninguna acción. De lo contrario, si el argumento no coincide con un puntero anteriormente devueltos por el calloc, malloc, o la función realloc, o si el espacio ha sido desasignado por una llamada para liberar o realloc, el comportamiento es indefinido