2008-09-07 38 views
18

Así que tengo un puntero a una matriz de punteros. Si lo elimino así:C++ borrar un puntero a un puntero

delete [] PointerToPointers; 

¿Eliminará también todos los punteros apuntados? Si no, ¿tengo que recorrer todos los punteros y eliminarlos también, o hay una manera más fácil de hacerlo? Mi google-fu no parece darme ninguna buena respuesta a esta pregunta.

(Y sí, sé que necesito usar un vector. Este es uno de esos "ponerse al día en C++" Asignaciones de tipos en la escuela.)

Respuesta

26

Sí, tiene que recorrer los punteros, eliminarlos individualmente.

Motivo: ¿Qué pasa si otro código tiene punteros a los objetos en su matriz? El compilador de C++ no sabe si es cierto o no, por lo que debe ser explícito.

Para una "manera más fácil", dos sugerencias: (1) Haga una subrutina para este fin, de modo que al menos no tenga que escribir el código más de una vez. (2) Utilice el paradigma de diseño de "puntero inteligente" donde mantenga una matriz de objetos con contadores de referencia, luego los objetos se eliminarán cuando los objetos ya no estén referenciados por ningún código.

1

Creo que vas a tener que bucle sobre I 'tengo miedo.

3

Los punteros son prácticamente referencias de memoria y no pequeños objetos de autofrenado .net. Crear destructores adecuados para cada clase hará que la eliminación sea un poco más limpia que los bucles masivos en todo el código.

16

Estoy de acuerdo con Jason Cohen, aunque podemos aclarar un poco el motivo por el que necesitamos eliminar los punteros con el ciclo. Para cada asignación de memoria "nueva" o dinámica, debe haber una "eliminación" de una asignación de memoria. Algunas veces la "eliminación" puede ocultarse, como con los smartpointers, pero aún está allí.

int main() 
{ 
    int *pI = new int; 
    int *pArr = new int[10]; 

Hasta ahora en el código hemos asignado dos trozos de memoria dinámica. El primero es solo un int general, el segundo es un conjunto de ints.

delete pI; 
    delete [] pArr; 

estas instrucciones delete borrar la memoria que fue asignada por el "nuevo" s

int ppArr = new int *[10]; 

    for(int indx = 0; indx < 10; ++indx) 
    { 
    ppArr[indx] = new int; 
    } 

Este bit de código está haciendo tanto de las asignaciones anteriores. Primero, estamos creando espacio para nuestro int en una matriz dinámica. Luego, debemos recorrer y asignar un int para cada punto de la matriz.

for(int indx = 0; indx < 10; ++indx) 
    { 
    delete ppArr[indx]; 
    } 
    delete [] ppArr; 

Observe el orden en que asigné esta memoria y luego la desasigné en el orden inverso. Esto es porque si tuviéramos que hacer el delete [] ppArr; primero perderíamos la matriz que nos dice cuáles son nuestros otros indicadores. Ese trozo o memoria se devolvería al sistema y, por lo tanto, ya no se puede leer con fiabilidad.

int a=0; 
    int b=1; 
    int c=2; 

    ppArr = new int *[3]; 

    ppArr[0] = &a; 
    ppArr[1] = &b; 
    ppArr[2] = &c; 

Esto, creo, debería mencionarse también. El hecho de que esté trabajando con punteros no significa que la memoria a la que apuntan esos punteros haya sido asignada dinámicamente. Es decir, solo porque tenga un puntero no significa que necesariamente deba eliminarse. La matriz que creé aquí está asignada dinámicamente, pero los punteros apuntan a instancias locales de ints. Cuando eliminamos esto, solo necesitamos eliminar la matriz.

delete [] ppArr; 

    return 0; 

} 

Al final de memoria asignada dinámicamente puede ser complicado y de todos modos se puede envolver de manera segura como en un puntero inteligente o mediante el uso de contenedores STL en lugar de su cuenta puede hacer su vida mucho más agradable.

4

Consulte boost pointer container para ver un contenedor que elimina automáticamente los punteros que contiene, mientras mantiene una sintaxis muy similar a los contenedores STL comunes.

+0

¡Bonito, no sabía sobre eso! – Frank

0

No sé por qué esto fue contestado tan confusamente largo.

Si elimina la matriz de punteros, liberará la memoria utilizada para una serie de entradas normales.
un puntero a un objeto es un número entero que contiene la dirección.

Has eliminado un grupo de direcciones, pero no hay objetos.

delete no le importa el contenido de un espacio de memoria, llama a destructor (es) y marca la memoria como libre.

No le importa que simplemente borre un grupo de direcciones de objetos, simplemente ve las entradas.

¡Es por eso que primero tiene que recorrer la matriz! y llame a eliminar en cada elemento, luego puede eliminar el almacenamiento de la matriz en sí.

Bueno, ahora mi respuesta tiene algo largo ... .... extraño ...;)

Editar: respuesta de Jason no está mal, simplemente no dio en el clavo. Ni ni el compilador ni nada en c (++) se preocupa por la eliminación de cosas que están en otra parte apuntadas. Puedes hacerlo. Las partes de otros programas que intenten utilizar los objetos eliminados segmentarán su error. Pero nadie te obstaculizará. Tampoco será un problema destruir una matriz de punteros a objetos, cuando los objetos se mencionan en otra parte.

+0

"Otras partes del programa que intenten usar los objetos eliminados te segmentarán por defecto" ... segfaulting es probablemente el mejor resultado posible, atrapa el lugar donde está el problema.Pero hay muchas otras posibilidades, que no se notarán hasta más tarde e incluso podrían causar corrupción tras la finalización del programa (si se asignó un búfer de escritura de archivo en la memoria ahora libre, por ejemplo). –

3

Echemos un (pseudocoded) ejemplo del mundo real .Imagine que tenía una clase como esta:

class Street 
{ 
    public: 
     Street(); 
     ~Street(); 
    private: 
     int HouseNumbers_[]; 
} 

typedef *Street StreetSign; 

Si usted tiene una serie de muestras de la calle, y se elimina la matriz de streetsigns, que doesn' Esto significa que elimina automáticamente los mensajes. Todavía están allí, ladrillos y cemento, simplemente ya no tienen esos signos que los señalen. Se ha deshecho de instancias específicas de de punteros a las calles.

Una matriz de punteros es (conceptualmente) un poco como una matriz de enteros, es una matriz de números que representan las ubicaciones de memoria de varios objetos. No son los objetos en sí mismos.

Si elimina [] la matriz de punteros, todo lo que ha hecho es eliminar una matriz de enteros.

Cuestiones relacionadas