2010-05-17 15 views
13
char *pointer1; 
char *pointer2; 

pointer1 = new char[256]; 
pointer2 = pointer1; 

delete [] pointer1; 

En otras palabras, ¿tengo que hacer delete [] pointer2 también?¿Es esto una pérdida de memoria?

Gracias!

+27

Como regla general, el # de 'borrar' debe usualmente coincide con el # de 'nuevo' – Amber

+0

No elimina los punteros, elimina las cosas que señalan. – immibis

Respuesta

17

No, ese código es correcto y no perderá memoria.

Solo tiene que usar eliminar [] una vez porque solo ha usado una nueva para asignar un área para la memoria, aunque haya dos punteros a esa misma memoria.

+12

Correcto. De hecho, ** no debes ** - intentar 'borrar' el mismo bloque de memoria dos veces daría lugar a un comportamiento indefinido. –

+4

También se debe tener en cuenta que cualquier intento de deferencia 'pointer2' dará como resultado un comportamiento indefinido, también. –

+0

side ... Como está aprendiendo ... Diría que es una buena idea establecer pointer1 = NULL; Como reflejo de la eliminación. He visto un montón de código donde se borra el puntero pero luego la aplicación hace un if (puntero1) .. – baash05

0

Sólo utilice Delete cuando se ha usado nuevo

Buena practive es establecer pointer2 a NULL, pero no tendrá una pérdida de memoria si no

1

delete borra la memoria que estaba asignado por new. Como solo tiene un new, solo necesita uno delete.

7

Una regla simple: necesita tantos delete s como new s. Aún mejor, use algo como un puntero inteligente o un contenedor para encargarse de ello.

Y otro punto secundario: pointer2 se está convirtiendo en un "puntero colgante" una vez que llame al delete en pointer1.

+2

tenga en cuenta que puntero1 también se convierte en un puntero colgante después de la eliminación ... –

+0

Muy cierto, pero pensé que era más obvio :) –

0

No, no tiene que borrar [] pointer2 porque no ha asignado memoria para ello.

La instrucción pointer2 = pointer1 hace que pointer2 señale a la misma dirección de memoria que pointer1, no asigna memoria extra para la misma.

+0

Um ... 'pointer2' apunta a la misma dirección * como *' pointer1', lo hace no apunte a la dirección de 'pointer1' (la dirección de' pointer1' sería '& pointer1'. –

+0

@Nathan Ernst: Lo siento, lo escribí mal. Corregí – nico

0

Cada new debe tener uno, y solo uno, que coincida con delete. Si eliminaste el otro puntero, romperías esa regla.

0

Lo que hace aquí es simplemente decir que el bloque de memoria asignado por new char[256] se apuntará por pointer1 y pointer2 en el mismo momento.

Sería una pérdida de memoria si escribió la declaración delete[] pointer2; después.

+2

Sería un comportamiento indefinido si eliminara el puntero2. En la práctica, no lo hago conozca una plataforma única donde podría provocar una pérdida de memoria. Lo más probable es que obtenga algo como segfault/AV. –

2

A pesar de que no hay fugas de memoria, si quieres ser explícita, se debe configurar tanto point1 y point2 a NULL (y les inicializar esa manera también.)

4

No es una fuga, pero está pidiendo para problemas pointer2 apunta a quién sabe qué tan pronto como elimine pointer1. Es lo que se llama un "puntero colgante". Usarlo puede, en el mejor de los casos, provocar una segfault y, en el peor de los casos, puede ocasionar que se arruinen datos misteriosos en cualquier cosa que termine asignando ese mismo lugar.

0

Aquí está la brecha en su forma de pensar: Usted no borra los punteros: elimina la memoria. Simplemente use un puntero para identificar el bloque de memoria que se liberará. Como las dos variables apuntan a la misma memoria, eliminar una es precisamente equivalente a eliminar la otra. En otras palabras, eliminar ambos es lo mismo que eliminar uno de ellos dos veces, lo cual es obviamente incorrecto.

2

Además, considere usar boost::shared_ptr<> de las bibliotecas de Boost. Es lo mejor desde el pan rebanado.Se eliminarán

typedef boost::shared_ptr<TypeX> StrRef; 

foo() { 
    StrRef pointer1(new TypeX); 

    while(something) { 
    StrRef pointer2 = pointer1; 
    // do stuff 
    } 

return; 
} 

Los datos (TypeX) cuando el último puntero a él se sale del ámbito. Se puede hacer algo similar con la incorporada en el auto_ptr<> tipo, si usted no necesita una cuenta de referencia:

typedef auto_ptr<TypeX> StrRef; 

foo() { 
    StrRef pointer1(new TypeX); 

    while(something) { 
    TypeX * pointer2 = pointer1.get(); 
    subroutine(pointer2); 
    if (condition) return; 
    } 

return; 
} 

Siempre pointer1 sale del ámbito, se eliminarán los datos. La ventaja de esto es que no tiene que recordar poner una eliminación antes de la instrucción de devolución en la parte inferior, y si pointer1 queda fuera del alcance por cualquier otra razón (es decir, regresar desde la mitad del ciclo o subroutine() arroja una excepción , a continuación, los datos aún se desasigna correctamente.

no he probado este código, por lo que tendrá que comprobar la documentación para auto_ptr<> y boost::shared_ptr<> mismo.

le recomiendo usar las bibliotecas Boost tanto como sea posible. Está escrito por profesionales, es básicamente un área de preparación para extensiones a C++.

Cuestiones relacionadas