2009-11-17 9 views
7

Después de que hago, digoC++ delete tabla de sintaxis del operador

Foo* array = new Foo[N];

Siempre he borrado de esta manera

delete[] array;

Sin embargo, a veces me he visto de esta manera:

delete[N] array;

Como parece que compila y funciona (al menos en msvc2005), me pregunto: ¿Cuál es la forma correcta de hacerlo? ¿Por qué compila de la otra manera, entonces?

Respuesta

13

Puede consultar este enlace de MSDN: delete[N] operator. El valor es ignorado

EDITAR Probé este código de ejemplo en VC9:

int test() 
{ 
    std::cout<<"Test!!\n"; 
    return 10; 
} 

int main() 
{ 
    int* p = new int[10]; 
    delete[test()] p; 
    return 0; 
}; 

de salida es: Prueba !!

Entonces la expresión se evalúa pero se ignora el valor de retorno. Estoy sorprendido de decir lo menos, no puedo pensar en un escenario por el cual esto es necesario.

+0

+1. información útil –

+0

significa que puede eliminar la matriz [2N]; y eso compilaría –

+0

Gracias, esto es lo que estaba buscando. – raven

5

delete[] array; es la forma correcta.

4

La manera correcta es hacer delete[] array;. Ni siquiera sabía que compilaría delete[N] array; (y lo dudo que debería).

+1

Compila en VC9 con un 'warning C4208: extensión no estándar utilizada: delete [exp] - exp evaluado pero ignorado' No sé lo que significa – Naveen

+1

Significa que el código es (1) no válido C++, y (2) la expresión 'N' se evalúa pero se ignora. Eso es bastante irrelevante, pero describe lo que sucede si escribió 'eliminar [N ++] matriz;' - N primero se incrementa y luego se ignora. – MSalters

+0

Realmente, primero se ignora y luego se incrementa :) – raven

5

Si el segundo caso es correcto o no, recomiendo usar el primero ya que es menos propenso a errores.

Visual Studio compila muchas cosas que no debería.

+4

"Visual Studio compila muchas cosas que no debería". Amén. – sbi

10

delete [N] array no es válida. No está definido en el estándar de C++: la sección 5.3.5 define una expresión de eliminación como delete expr o delete [] expr, y nada más. No se compila en gcc (versión 4.1.2). En cuanto a por qué se compila en Visual C++: pregunte a Microsoft.

+0

¿Qué estándar de C++? Y, ¿tienes un enlace/ref, donde uno puede encontrarlo? – Kissaki

+1

@Kissaki: Me habría estado refiriendo a C++ 03, que no está disponible legalmente en línea. Sin embargo, la redacción es muy similar en C++ 11, cuyo borrador está disponible en http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf –

+0

Ah, gracias .. – Kissaki

-2

si funciona, es una extensión no estándar.

delete [] array; 

tiene la forma correcta.

delete array; 

a veces también funciona, pero depende de la implementación (por lo tanto, es incorrecto).

+1

El comportamiento de la segunda forma (sin los corchetes) está claramente definido para punteros que no son de matriz. Su comportamiento para las matrices no lo es. De todos modos, creo que esa es la razón por la que alguien votó en contra. –

+1

'delete array' no funciona en ningún sentido de la palabra, a menos que quiera decir que no bloquea el programa. No recuperará toda la memoria asignada en primer lugar y, si no se bloquea, solo ejecutará el destructor en el primer objeto de la matriz. (Lo cual también es un error si hiciste 'nuevo Foo [0]'.) – Bill

+1

@Bill: Desearía poder votar por los comentarios. Su declaración puede ser cierta a veces y en otras ocasiones puede que no. Vea aquí: http://stackoverflow.com/questions/1553382/1553407#1553407 y mi comentario aquí: http://stackoverflow.com/questions/1553382/1553391#1553391 – sbi

4

Primer punto: casi nunca hay una buena razón para usar la forma de matriz de nuevo o eliminar para empezar - use std :: vector (o algún otro contenedor) en su lugar.

Segundo: en las edades oscuras de C++, tenía que especificar el tamaño de la matriz que estaba eliminando, por lo que si usó x = new T[N], la eliminación correspondiente fue delete [N] x. El requisito de especificar explícitamente el tamaño se eliminó hace largo, pero algunos compiladores (especialmente aquellos que se preocupan por la compatibilidad con código antiguo) todavía lo permiten.

A menos que realmente necesite seguir siendo compatible con un compilador antiguo (uno que tiene 20 años o menos) no debe usarlo. Por otra parte, a menos que necesites seguir siendo compatible con un compilador tan antiguo que no admite ningún contenedor estándar, no deberías estar usando la matriz de nuevo o eliminar en primer lugar. ¡Solo para!

+0

Gracias por la lección de historia. Entonces, si tuviera que pasar una matriz dinámica de, por ejemplo, flotadores, a una biblioteca de terceros, ¿cuál sería la manera correcta de hacerlo con contenedores estándar? – raven

+0

Usa un vector. Cuando necesite pasar la dirección/longitud, use & vec [0], y vec.size(). –

+0

+1: En el borrador del estándar de septiembre de 1994, la sintaxis ya era 'eliminar []'. Y en el mismo año, Design and Evolution (p218) tuvo el comentario de que esta sintaxis "... demostró ser demasiado propensa a errores, por lo que la carga de mantener un registro del número de elementos se puso en la implementación en su lugar". –