2011-10-04 23 views
6

He creado un bloque de código, como este.cuando se lanzará la memoria?

proc() 
{ 
    Z* z = new Z(); 
} 

ahora el puntero declarado dentro del método proc tendrá alcance solo hasta proc. Quiero preguntar cuándo se llamará automáticamente a DTOR for z. ya sea cuando los controles salen del procedimiento proc o cuando mi aplicación está cerrada.

Respuesta

1

DTOR no se abrirá automáticamente. Debe usar la palabra clave "eliminar".

1

El destructor de Z no se llamará a menos que poner en una línea como la siguiente en el código:

delete z; 
17

El destructor no se llamará en lo absoluto. La memoria utilizada por *z se filtrará hasta que se cierre la aplicación (en ese momento, el sistema operativo recuperará toda la memoria utilizada por el proceso).

Para evitar la fuga, debe llamar al delete en algún momento o, mejor aún, usar punteros inteligentes.

4

Va a tener una pérdida de memoria a menos que pase z a delete.

+0

En el bloque de código en el que he declarado * z, he terminado con él, así que podría llamar "eliminar z" justo antes de devolver la instrucción del proceso. –

+1

@Apoorva: si nunca necesita '* z' fuera del bloque, no debe usar la asignación dinámica. Como escribió James Kanze, simplemente use 'Z z;' y el objeto se destruirá cuando 'proc()' regrese. – MSalters

12

Esto es una pérdida de memoria. Lo que probablemente debería tener es:

void 
proc() 
{ 
    Z z; 
} 

y omita la asignación dinámica. Si la duración de un objeto corresponde a su alcance, rara vez necesita una asignación dinámica.

Si por alguna razón necesita una asignación dinámica (por ejemplo, debido al polimorfismo ), entonces debe usar algún tipo de puntero inteligente; std::auto_ptr funciona bien aquí, y cosas como scoped_ptr, si las tienen, puede ser incluso mejor.

+0

Mejor uso unique_ptr si el compilador lo admite, y su scoped_ptr debe ser similar pero no es estándar – Geoffroy

+0

@Geoffroy 'unique_ptr' es solo un' auto_ptr' actualizado; si sabe que nunca tendrá que admitir un compilador anterior, puede usarlo. 'scoped_ptr' tiene una semántica mucho más limitada, ya que no admite la transferencia de propiedad. –

1

Cuando utiliza nuevo el objeto se asigna en el montón, el montón se comparte entre todas sus funciones en el programa, es decir, puede decir un poco, que el alcance de los objetos asignados es su programa sin hacer una eliminación en el objeto, existirá hasta que tu programa salga.

7

Este es uno de los fundamentos en C++.

asignación dinámica

En su caso, la asignación de memoria y la consiguiente llamada de constructor para Z que ocurrirá el new:

Z* z = new Z(); 

la parte opuesta de la destrucción y la cancelación de asignación de memoria que ocurrirá el delete :

delete z; 

Pero dado que su código no lo tiene, la desasignación de memoria nunca ocurrirá, y además perderá el puntero z sin posibilidades de desasignar el objeto en el futuro. Esto es una pérdida de memoria típica.

Declaración

Por otro lado, si se declara objeto como éste:

Z z; 

asignación de memoria y constructor serán llamados inmediatamente a la derecha aquí en el punto de declaración, y cuando el objeto de el alcance de la existencia ha finalizado (es decir, al final de la función) se llamará automáticamente al destructor y se desasignará la memoria.

dinámico de asignación vs Declaración

yo no voy a entrar en debates sobre lo que es mejor y lo que no lo es, sino que proporcionará el extracto de uno de los artículos que se vincula a continuación:

A diferencia de las declaraciones, que cargan datos en el segmento de datos de programas, la asignación dinámica crea un nuevo espacio utilizable en los programas STACK (un área de RAM específicamente asignada a ese programa).

FYI: Stack = Performance, pero not always the best solution.

Referencias

Para su placer: tictactoe.

+0

¿Cómo es esto fundamental en Java? ¿Quisiste decir "[..] diferencia entre C++ y Java"? – Simon

+0

Gracias, actualizado. Después de algunas modificaciones, la primera oración ya no es válida. –

Cuestiones relacionadas