2010-09-12 16 views
9

¿Por qué hay un delete[]? Según mi entender, se comporta de manera diferente para las matrices. Sin embargo, ¿por qué existe realmente? Solo está disponible en C y no en free_array. También en sintaxis, la única diferencia entre delete var y delete []var es [] que no tiene params (no estoy diciendo la longitud de la matriz).¿Por qué hay una eliminación [] en C++?

¿Por qué realmente existe delete[]? Sé que alguien dirá que puede sobrecargar delete y delete[] (al menos eso creo que es posible) pero digamos que no lo estamos sobrecargando. ¿Por qué existe?

+1

La razón obvia para que delete [] sea es que llamará a destructores para los elementos de la matriz. Ver http://stackoverflow.com/questions/659270/why-is-there-a-special-new-and-delete-for-arrays –

+0

Quizás una pregunta más interesante sería por qué 'delete []' (and 'new [] ') existen cuando tienes' std :: vector'. – jamesdlin

+2

@jamesdlin: ¿Porque no siempre tenemos 'std :: vector'? ¿Y porque 'std :: vector' no funcionaría sin ellos? –

Respuesta

19

Normalmente, para las clases que no son POD, una expresión delete[] debe invocar destructores en un número variable de instancias de clases que no se pueden determinar en tiempo de compilación. El compilador generalmente tiene que implementar alguna "magia" de tiempo de ejecución que se puede usar para determinar la cantidad correcta de objetos para destruir.

Una expresión delete no tiene que preocuparse por esto, simplemente tiene que destruir el único objeto al que apunta el puntero suministrado. Debido a esto, puede tener una implementación más eficiente.

Al dividir delete y delete[], delete se puede implementar sin la sobrecarga necesaria para implementar correctamente delete[] también.

+0

+1: como siempre, en C++, no paga por lo que no necesita ... –

+0

¿Qué? ¿Podría alguien dar un ejemplo sobre dónde no se puede determinar el número de destructores en el tiempo de compilación? – lvella

+0

@Ivella: ¿Qué hay de esta función: 'void freearray (Type * x) {delete [] x; } ' –

3

Si elimina una matriz, solo se llamará al primer destructor de objetos. delete [] llama a los destructores de todos los objetos en la matriz y libera la memoria de la matriz.

+0

+1: pásame :-) –

+7

Si 'eliminas 'algo que fue el resultado de' nuevo xxx [N] ', obtienes _undefined behaviour_. Llamar al destructor solo al primer objeto es solo un posible resultado. –

3

Supongamos que delete [] no existe, escriba el código para eliminar la matriz y elimine solo el primer elemento de la matriz.

delete array;  // Deletes first element, oops  
delete &array;  // Deletes first element, oops 
delete &array[0]; // Deletes first element 

Un puntero a una matriz de ser un alias para un puntero al primer elemento de la matriz es por supuesto un viejo "característica" C.

+0

_ @ Hans_, esta es quizás una respuesta algo elíptica ... pero genial como una demostración de por qué 'delete []' es necesario. +1 – stakx

+1

@stakx: no demuestra que 'delete []' es * needed *, como tal - la implementación podría de alguna manera marcar si una asignación es una matriz o no, del mismo modo que actualmente rastrea la longitud de todas las asignaciones hechas con 'nuevo []'. Entonces 'delete' podría verificar la bandera y simplemente hacer lo correcto. Eliminar el primer elemento de una matriz siempre es incorrecto, por lo que no hay necesidad de una sintaxis para hacerlo. –

+0

Erm, no, difícil de implementar vector :: operador [] si no hubo sintaxis para eso. –

1

Considere:

int* a = new int[25]; 
int* b = a; 

delete b; // only deletes the first element 

El C++ compilador tiene ni idea de si b puntos a una matriz o un solo elemento. Llamar al delete en una matriz solo eliminará el primer elemento.

+1

Para ser justos, podría decir lo mismo para 'eliminar [ ] b'; ¿cómo sabe que hay 25 elementos en la matriz? La respuesta es metainformación detrás de escena. En principio, el compilador también podría almacenar una matriz booleana/bandera no de matriz en esta metainformación. Creo que la respuesta de Charles es la verdadera razón. –

+0

El [] le dice al compilador que hay metainformación. –

+2

Incluso el 'borrar' simple necesita metainformación para poder volver a liberar la memoria en el montón, por ejemplo, punteros a los bloques asignados anterior y siguiente o algo similar (depende en gran medida de la implementación). – fredoverflow

Cuestiones relacionadas