2008-12-13 11 views

Respuesta

18

Si está preguntando por qué las clases de C++ tienen destructores, algunas clases tienen requisitos además de liberar la memoria. Es posible que tenga un objeto que tiene asignada una conexión de socket que debe cerrarse limpiamente, por ejemplo.

Además, 'unscoping' un puntero no no libera la memoria que señala ya que otros punteros pueden estar haciendo referencia a ella.

Si tiene un puntero en la pila, salir de la función liberará la memoria utilizada por el puntero pero no esa memoria apuntada por el puntero. Hay una distinción sutil pero muy importante.

14

Cuando un puntero queda fuera del alcance, se libera la memoria tomada por con el puntero. Los 4 u 8 bytes (generalmente) de memoria que toma el puntero, es decir.

El objeto (u otra memoria) que el puntero apunta a es no libera cuando el puntero sale del ámbito. Lo haces por borrando 'puntero. Y eso invoca el destructor, si hay alguno.

0

Cuando haya un puntero (existe como miembro de clase), debe haber un destructor para esa clase que debe eliminar el objeto apuntado por el miembro del puntero. Si tiene smart_pointer en lugar de puntero en clase, entonces no hay necesidad de destructor.

below qn te ayudarán a comprender mejor. Will the below code cause memory leak in c++

9

En primer lugar, declara erróneamente que la memoria se libera cuando el puntero queda fuera del alcance. Con los punteros sin procesar que son falsos, la memoria se pierde y cualquier recurso retenido por el objeto puntiagudo.

Destructors son una característica central del lenguaje, y la base para el idioma RAII para la gestión de recursos. Los objetos adquieren recursos durante la construcción y liberan esos mismos recursos en el destructor. Es un enfoque simple, controlable y simple para la administración de recursos. Tenga en cuenta que este recurso es cualquier cosa desde la memoria (los destructores de punteros inteligentes liberan la memoria que controlan, los contenedores liberan su estructura de memoria interna) o cualquier otro recurso (de los flujos liberan archivos abiertos, las conexiones de bases de datos liberan los sockets).

Mientras que en los lenguajes administrados como C# o la memoria Java es liberada automáticamente por el recolector de basura, solo se libera la memoria y el usuario tiene la tensión de controlar todos los demás recursos manualmente en el lugar de uso.

Si comprueba las estructuras de control de excepciones en C#/Java, notará que hay una cláusula final que no existe en C++. La razón es que los lenguajes administrados deben proporcionar al usuario un bloque de código que se garantiza que se ejecutará para liberar manualmente los recursos. La tensión de liberar recursos se coloca en el programador que usa las bibliotecas.

En C++, utilizando la expresión RAII, cada objeto es responsable de los recursos que contiene y debe liberarlos durante la destrucción. Esto implica que si usa objetos en la pila, los recursos se liberarán sin la interacción del usuario. La responsabilidad de controlar los recursos está en la clase, y el usuario no debe recordar liberar cada recurso manualmente.

Muchos acusados ​​del lenguaje administrado con mucho gusto dicen que no tener que recordar cuándo o dónde liberar memoria, ya que será reclamado por el recolector de basura es una gran ventaja, pero no entrarán en la discusión de cómo se controlan otros recursos . La gestión de la memoria es solo un subconjunto del problema de la gestión de recursos y se aplica la misma solución. Si mantiene la memoria dentro de los punteros inteligentes (std :: auto_ptr, boost :: shared_ptr, std :: tr1 :: unique_ptr, std :: tr1 :: shared_ptr ..., elija la que se ajuste a su uso), entonces se administrará la memoria para ti.

Si bien esta publicación parece haberse salido de la cuestión original de los destructores, está muy relacionada. Todo el control de recursos debe realizarse en destructores, así es como funcionan los punteros inteligentes: cuando la pila asigna el puntero inteligente sale del ámbito se llama al destructor y comprueba si la memoria asignada en pila (nueva) debe liberarse y, en caso afirmativo, borrar se llama. Pero, de nuevo, esto es solo un subconjunto del problema más general.

0

Si está escribiendo bien C++, entonces debería tener muy pocos destructores (de hecho, creo que "pocos destructores" es una buena métrica para la calidad del código C++).

Un par de excepciones que puedo pensar son:

a) Cuando se trabaja con las cosas que no destruirse a sí mismos, por ejemplo. "ARCHIVO*".

b) Cuando utilizas el modismo "pimpl" (google para "idioma pimpl").

nb. Las clases como std :: auto_ptr y std :: vector entrarán en la categoría (a) porque en algún momento necesitan un puntero de estilo C para la memoria.

Cuestiones relacionadas