2011-05-18 14 views
11

Si tengo un programa en C, como:¿Hay algún daño al llamar "gratis" para el mismo puntero dos veces en un programa C?

SomeTypePtr my_type; 
my_type = malloc(sizeof(someType)); 

/* do stuff */ 

free(my_type); 

/* do a bunch of more stuff */ 

free(my_type); 

hace el llamado de 'libre' para my_type hacer ningún daño? Después de llamar a free (my_type), ¿el puntero se convierte en un puntero nulo una vez más?

+0

Ver http://en.wikipedia.org/wiki/Malloc#Use_after_free – Rooke

Respuesta

12

La desasignación de un área de memoria con free no convierte el contenido del puntero en NULL. Supongamos que tiene int *a = malloc (sizeof (int)) y a tiene 0xdeadbeef y ejecuta free (a) luego después de la ejecución a todavía contiene 0xdeadbeef pero después de la llamada free esta dirección de memoria ya no está reservada para usted. Algo así como usted ha alquilado un apartamento con malloc usado durante algún tiempo, devolvió el apartamento por free, entonces es posible que tenga una llave duplicada para el apartamento, pero no está reservado para usted.

Hacer un free en una memoria ya free dará como resultado una doble corrupción de memoria libre.

+0

oh, eso está muy claro, gracias. ¿Hay alguna manera de detectar si la memoria de un puntero ha sido desasignada? – Ash

+0

@Ash: ver mi respuesta. – titaniumdecoy

+0

Supongo que este es el motivo por el que veo algunos documentos de mejores prácticas que sugieren que siempre debe configurar manualmente los punteros a = NULL después de llamar a 'free (pointer)'. – Ash

3

Solo si consideras destruir tu montón de "daños". free() no hará que su puntero sea nulo.

+0

Así que, ¿cómo puedo probar para ver si un puntero ha sido liberado correctamente? – Ash

+0

La llamada siempre será exitosa, a menos que no haya nada para liberar, en cuyo caso se generará una falla de segmentación. –

+2

El artículo de la wikipedia que he vinculado tiene una respuesta bastante escueta pero sabia a esto: "La mejor práctica es que un puntero sale del alcance inmediatamente después de ser liberado". – Rooke

4
  1. No hará que su puntero sea NULO.
  2. Liberará la memoria apuntada por el puntero, dejando el puntero en un segmento de memoria no asignado.
  3. Si no utiliza malloc o calloc entre las llamadas, le dará una falla de segmentación.
  4. "La mejor práctica es que un puntero salga del alcance inmediatamente después de ser liberado". significa que el puntero debe permanecer en la pila para que no se establezca NULL explícitamente porque eventualmente quedará fuera del alcance y se liberará.
+3

Le dará un 'SEGV' _si tiene suerte_. :) – sarnold

3

Sin repetir las otras respuestas, le corresponde anular los punteros una vez que haya llamado al free(). Llamar al free() dos veces en la misma asignación dará como resultado la corrupción del montón.

SomeTypePtr my_type; 
my_type = malloc(sizeof(someType)); 

/* do stuff */ 

free(my_type); 
my_type = 0; // Throw away the pointer to released memory, so cannot either free it or use it in any way. 

/* do a bunch of more stuff */ 

free(my_type); // OK now - calling free(0) is safe. 
Cuestiones relacionadas