2008-10-13 17 views
22

Siempre me he preguntado si existe un operador para eliminar matrices multidimensionales en el lenguaje C++ estándar.Por qué "delete [] [] ... multiDimensionalArray;" el operador en C++ no existe

Si hemos creado un puntero a una matriz unidimensional

int *array = new int[size]; 

las miradas de borrado como:

delete [] array; 

Eso es grande. Pero si tenemos matriz de dos dimensiones, que no podemos hacer

delete [][] twoDimenstionalArray; 

En su lugar, debe reproducirse y eliminar los artículos, como en el ejemplo this.

¿Alguien puede explicar por qué?

Respuesta

25

Técnicamente, no hay dos matrices dimensionales en C++. Lo que está usando como una matriz bidimensional es una matriz unidimensional con cada elemento como una matriz unidimensional. Como técnicamente no existe, C++ no puede eliminarlo.

0

delete [] se aplica a cualquier matriz no escalar.

+0

No, provocará una pérdida de memoria si intenta eliminar [] una matriz dentada. –

4

no estoy seguro de la razón exacta desde el punto de vista del diseño del lenguaje, supongo que tiene algo que ver con el hecho de que al asignar memoria está creando un conjunto de matrices y cada una necesita ser eliminada.

int ** mArr = new int*[10]; 
for(int i=0;i<10;i++) 
{ 
    mArr[i]=new int[10]; 
} 

mi C++ está oxidado, no estoy seguro si eso es sintácticamente correcto, pero creo que está cerca.

7

La razón por la que se llama eliminar varias veces en ese ejemplo se debe a que se llama varias veces también. Se debe llamar a Delete para cada nuevo.

Por ejemplo, si asigno 1,000,000 de bytes de memoria, no puedo eliminar las entradas de 200,000 - 300,00, se asignó como un trozo entero y debe liberarse como un trozo entero.

+2

Por lo tanto, el opuesto también es verdadero; si se asignó como múltiples fragmentos, debe liberarse como múltiples fragmentos –

+1

Sí, mi punto es exactamente el mismo. – KPexEA

20

Debido a que no hay manera de llamar

int **array = new int[dim1][dim2]; 

Todas las noticias/eliminaciones deben ser equilibradas, por lo que no tiene sentido para un operador de delete [][].

new int[dim1][dim2] devuelve un puntero a una matriz de tamaño dim1 del tipo int[dim2]. Por lo tanto, dim2 debe ser una constante de tiempo de compilación. Esto es similar a la asignación de matrices multidimensionales en la pila.

+1

es al revés. dim2 debe ser una constante de tiempo de compilación, mientras que dim1 no tiene que ser así, y se devuelve un int (*) [dim2] :) puede memorizar la sintaxis al imaginar lo que sucede si lo hace int v [dim1] [dim2 ]; y compruebe el tipo de v después de la descomposición en un puntero: es int (*) [dim2]; –

6

La razón por la que tiene que realizar un ciclo, como en el ejemplo que menciona, es que el compilador/asignador no conoce la cantidad de matrices que debe eliminar.

Cuando asignó su matriz bidimensional, realmente creó N matrices unidimensionales. Ahora cada uno de ellos tiene que ser eliminado, pero el sistema no sabe cuántos de ellos hay. El tamaño de la matriz de nivel superior, es decir, la matriz de punteros a las matrices de segundo nivel, es como cualquier otra matriz en C: el sistema no almacena su tamaño.

Por lo tanto, no hay forma de implementar delete [][] como usted describe (sin cambiar el idioma significativamente).

0

Puede usar una clase contenedora para hacer todo eso por usted. Normalmente, trabajar con tipos de datos "primitivos" no es una buena solución (las matrices deben estar encapsuladas en una clase). Por ejemplo std :: vector es un muy buen ejemplo que hace esto.

Eliminar debe llamarse exactamente cuántas veces se llama nuevo. Como no puede llamar "a = new X [a] [b]", tampoco puede llamar a "delete [] [] a".

Técnicamente es una buena decisión de diseño que evita la aparición de una inicialización extraña de una matriz n-dimensional completa.

0

Bueno, creo que es fácil de implementar, pero demasiado peligroso. Es fácil saber si se creó un puntero por new[], pero es difícil saber new[]...[] (si está permitido).

3

Si bien todas estas respuestas son relevantes, voy a tratar de explicar lo que llegó a una expectativa, que algo como delete[][] array; pueden trabajar en matrices asignados dinámicamente y por qué no es posible:

La sintaxis int array[ROWS][COLS]; admiten bajo estáticamente matrices asignadas es solo una abstracción para los programadores, que en realidad crea una matriz unidimensional int array[ROWS*COLS];. Pero durante el proceso de compilación (cuando los tamaños de dimensión COLS y ROWS deben ser constantes por estándar), el compilador también recuerda el tamaño de esas dimensiones, que son necesarias para dirigir los elementos más adelante utilizando sintaxis, p. array[x][y] = 45. El compilador, al ser conocido de este tamaño, reemplazará [x][y] con el índice correspondiente a una matriz unidimensional usando matemática simple: [COLS*x + y].

Por otro lado, este no es el caso con dinámicamente matrices asignadas, si desea la misma funcionalidad multidimensional (de hecho, notación). Como su tamaño se puede determinar durante el tiempo de ejecución, también tendrían que recordar el tamaño de cada dimensión adicional para su uso posterior, y recordar eso durante toda la vida de la matriz. Además, los cambios del sistema tendrían que implementarse aquí para trabajar con matrices en realidad como multidimensionales, dejando la forma de anotación de acceso [x][y] en el código, no reemplazándola con una notación unidimensional durante la compilación, sino más tarde reemplazándola en el tiempo de ejecución.

lo tanto, un ausencia dearray = new int[ROWS][COLS] implica que no hay necesidad de delete[][] array;. Y como ya se mencionó, no se puede utilizar en su ejemplo para eliminar su matriz "multidimensional", ya que sus sub-arrays (dimensiones adicionales) se asignan por separado (usando la llamada new por separado), por lo que son independientes de la parte superior array (array_2D) que los contiene y no se pueden eliminar todos a la vez.

Cuestiones relacionadas