¿Qué sucede cuando desasignas un puntero dos veces o más en C++?


int main(){
Employee *e = new Employee();

delete e;
delete e;
...
delete e;
return 0;

}
Author: Michael Mrozek, 2010-04-30

7 answers

e'no es una referencia, es un puntero. Se obtiene comportamiento indefinido si se intenta delete un objeto a través de un puntero más de una vez.

Esto significa que casi cualquier cosa puede pasar de 'parecer que funciona' a 'estrellarse' o algo completamente aleatorio.

 38
Author: CB Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 18:13:41

Es un comportamiento indefinido, por lo que cualquier cosa puede suceder.

Lo que es probable que suceda es malo. Típicamente, la tienda libre es un sistema cuidadosamente administrado de bloques libres y asignados, y new y delete hacen la contabilidad para mantener todo en un estado consistente. Si delete de nuevo, es probable que el sistema haga la misma contabilidad en datos no válidos, y de repente la tienda gratuita está en un estado inconsistente. Esto se conoce como "corrupción de montón".

Una vez que eso sucede, cualquier cosa que hagas con new o delete pueden tener resultados impredecibles, que pueden incluir intentar escribir fuera del área de memoria de la aplicación, corromper datos silenciosamente, pensar erróneamente que no hay más memoria, o asignación doble o superpuesta. Si tienes suerte, el programa se bloqueará pronto, aunque todavía tendrás problemas para averiguar por qué. Si tienes mala suerte, seguirá funcionando con malos resultados.

 18
Author: David Thornley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 18:19:19

Aparte del viejo saw sobre "comportamiento indefinido" que significa que cualquier cosa podría pasar de la nada a una puerta de entrada al séptimo círculo del infierno que se abre en la memoria principal, en la práctica lo que generalmente sucederá en la mayoría de las implementaciones es que el programa continuará corriendo más allá de las eliminaciones, y luego misteriosamente se bloqueará algún tiempo después en alguna asignación de memoria no relacionada.

 11
Author: Crashworks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 18:17:08

Es probable que se aventure en un territorio de "comportamiento indefinido".

En muchos sistemas esto causará un bloqueo; por ejemplo, en mi máquina Linux:

*** glibc detected *** ./cctest: double free or corruption (fasttop): 0x0000000000d59900 ***
======= Backtrace: =========
/lib/libc.so.6[0x7f399f4cbdd6]
/lib/libc.so.6(cfree+0x6c)[0x7f399f4d074c]
./cctest[0x400a7a]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f399f474abd]
./cctest[0x400959]
 4
Author: John Ledbetter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 18:15:31

Si tienes mucha suerte, se estrellará. Lo que normalmente sucede es que almacena karma hasta que su CEO esté demostrando el código a su nuevo cliente más importante cuando corromperá/destruirá todos sus datos.

En compilaciones verificadas o de depuración a menudo este tipo de cosas se captan, pero pueden pasar completamente desapercibidas y causar estragos más tarde. Esto es especialmente profundo cuando se involucran múltiples hilos.

 3
Author: Stewart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 18:48:28

No es seguro, y no está definido lo que realmente podría suceder:

Http://www.parashift.com/c++ - faq-lite / freestore-mgmt.html # faq-16.2

 2
Author: John Weldon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 18:13:48

Si le preocupa que esto pueda suceder en sus aplicaciones, deje de usar punteros raw por completo, de modo que no necesite eliminar (por ejemplo, cambiar a shared_ptr) o establezca siempre punteros a NULL (o 0, o mejor aún nullptr) después de eliminarlos. Llamar a delete en un puntero nulo está garantizado para no hacer nada.

 2
Author: Kate Gregory,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 20:38:00