2010-08-17 9 views
5

¿Realmente funciona en algunos compiladores/máquinas, pero en otros causa corrupciones y bloqueos?¿Por qué llamar a free() en un puntero asignado con 'nuevo' causa corrupción de montón?

¿Alguien tiene alguna idea de lo que sucede bajo las sábanas?

+0

Obtiene un comportamiento indefinido, ahora y para siempre. [No lo hagas.] (Http://www.parashift.com/c++faq-lite/freestore-mgmt.html#faq-16.3) – GManNickG

+8

Él te pregunta por qué obtienes este comportamiento, solo diciéndole que no lo haga. no ayuda aún más su comprensión de nada. – bobDevil

+1

@bobDevil: Bien, el comportamiento no está definido por el estándar de C++, lo que significa que los implementadores de lenguaje no sentirán ningún deseo de imponer un comportamiento razonable. No existe un comportamiento tradicional (que no sea "¡No hagas eso!"), Así que ni siquiera hay un estándar informal. Empíricamente, el comportamiento parece variar. Por lo tanto, no puede contar con ningún comportamiento en particular, y ningún ingeniero compilador le dará ninguna simpatía. Esa es razón suficiente para decir "¡No lo hagas!" sin entrar en ninguna explicación de por qué ocurre un comportamiento en particular. –

Respuesta

17

C++ desea llamar a un destructor en el objeto cuando usa delete, pero pasarlo a free no permite que esto suceda. Si el objeto contenía otros objetos, tampoco se llamarían a los destructores de esos objetos. Si el objeto tenía punteros, entonces esos no serían liberados.

Adicionalmente C++ 's new y delete realidad podría solicitar una mayor cantidad de memoria desde malloc y utilizar el extra para la contabilidad (como el almacenamiento de la dirección de la función de destructor), por lo que el puntero que pasó a free no sería en realidad una eso fue malloc ed.

2

La norma dice que tiene que coincidir con la función de asignación/desasignación perfectamente (new - delete, new[] - delete[], malloc - free). Teóricamente, es bastante posible que algunos compiladores implementen operator new() como un simple malloc(), por lo que no causaría un bloqueo, sino que "solo" saltaría la llamada al destructor (que es malo por sí mismo). Sin embargo, operator[] puede almacenar el número de elementos en el trozo de memoria asignado, en cuyo caso, la dirección devuelta por new[] apunta dentro de un bloque asignado por malloc() (no al principio), lo que significa que no puede liberarlo con free().

2

El nuevo operador también se puede cargar. Si alguien escribió un nuevo operador que estaba haciendo algo completamente diferente, por ejemplo, tomar punteros de un grupo de memoria, llamar a esos punteros gratis podría ser muy peligroso.

+1

... llamando 'free' en esos punteros ... – Potatoswatter

Cuestiones relacionadas