2010-10-11 17 views
18

He intentado buscar pero no he encontrado nada con una respuesta definitiva. Sé que mi problema no puede ser tan difícil. Tal vez es solo que estoy cansado ...Declarar un puntero a una matriz multidimensional y asignar la matriz

Básicamente, quiero declarar un puntero a una matriz bidimensional. Quiero hacerlo de esta manera porque eventualmente tendré que cambiar el tamaño de la matriz. He hecho lo siguiente con éxito con una matriz 1D:

int* array; 
array = new int[somelength]; 

me gustaría hacer lo siguiente con una matriz 2D pero no va a compilar:

int* array; 
array = new int[someheight][somewidth]; 

El compilador me da un error que indica ese 'algún ancho' no puede aparecer en una expresión constante. Intenté todo tipo de combinaciones de ** y [] [], pero ninguno de ellos parece funcionar. Sé que esto no es tan complicado ... Se agradece cualquier ayuda.

Respuesta

12

Acabo de encontrar que esta antigua respuesta aún se lee, lo cual es una pena ya que está mal. Mira the answer below con todos los votos en su lugar.


Leído en la sintaxis del puntero, necesita una matriz de matrices. Que es lo mismo que un puntero a un puntero.

int width = 5; 
int height = 5; 
int** arr = new int*[width]; 
for(int i = 0; i < width; ++i) 
    arr[i] = new int[height]; 
+2

¿Has probado esto? No compila (si el alto y el ancho son ambas variables) –

+0

Sí, lo he intentado y todavía obtengo el mismo error con el compilador. dirá que "'ancho' no puede aparecer en una expresión constante" – vince88

+1

Si tuviera acceso a un elemento de esta matriz, ¿sería simplemente arr [ancho] [alto]? – vince88

5

A listo para usar ejemplo de here, después de algunos segundos de googlear con la frase "dos matriz dinámica dimensional":

int **dynamicArray = 0; 

// memory allocated for elements of rows. 
dynamicArray = new int *[ROWS]; 

// memory allocated for elements of each column. 
for(int i = 0 ; i < ROWS ; i++) { 
    dynamicArray[i] = new int[COLUMNS]; 
} 

// free the allocated memory 
for(int i = 0 ; i < ROWS ; i++) { 
    delete [] dynamicArray[i]; 
} 
delete [] dynamicArray; 
+2

Esta es una matriz de matrices, no realmente una 2D. –

+3

@Alexander Rafferty: Ya veo: ¿cuál es la diferencia entre "matriz de matrices" y "matrices 2D"? – Arun

+5

@ArunSaha, esto es antiguo, pero para responder a su pregunta y para cualquier otra persona que tropiece con esto, un 2- D matriz es contigua en la memoria, una matriz dinámica de matrices dinámicas es contigua en la primera dimensión, pero cada matriz en la segunda dimensión se almacena por separado –

33
const int someheight = 3; 
const int somewidth = 5; 

int (*array)[somewidth] = new int[someheight][somewidth]; 
+6

A diferencia de las otras respuestas aquí, esta en realidad responde a la pregunta, que era cómo declarar un puntero a una matriz multidimensional, no una matriz dentada. Esta es una diferenciación importante para las aplicaciones sensibles al rendimiento. Funciona si "somewidth" es una constante y solo cambia "someheight". Si nos fijamos en cómo esta matriz 2D se presenta en la memoria, está todo junto y contiguo, con no más de la única asignación de memoria "nueva". La respuesta de Alexander Rafferty también es buena si el ancho también es dinámico. Las otras respuestas son lentas porque hacen una tonelada de mallocs ... –

4

se sugiere emplear un método mucho más simple que una matriz de matrices:

#define WIDTH 3 
#define HEIGHT 4 

int* array = new int[WIDTH*HEIGHT]; 
int x=1, y=2, cell; 
cell = array[x+WIDTH*y]; 

Creo que este es un mejor enfoque que una matriz de una matriz, ya que no es fa r menos asignación. Incluso se puede escribir una macro ayudante:

#define INDEX(x,y) ((x)+(WIDTH*(y))) 

int cell = array[INDEX(2,3)]; 
1

Creo que esto va a hacer

int r, c ; 
std::cin>>r>>c ; 
int *array = new int[r*c] ; 

Puede introducir los valores por hacer algo como esto

for (int i = 0 ; i < r ; i++){ 
    for (int j = 0 ; j < c ; j++){ 
     std::cin>>array[i *c + j] ; 
    } 
} 
2

Personalmente, mi preferencia es utilice un truco sintáctico para declarar un puntero a la matriz multidimensional de tamaño dinámico. Esto funciona en compiladores que soportan matrices de longitud variable (VLA), que todos los compiladores de C++ deben tener, y la mayoría de los compiladores de C actuales.

La idea básica es capturado en esto:

void bar (int *p, int nz, int ny, int nx) { 
    int (*A)[ny][nx] = (int(*)[ny][nx]) p; 

puntos "p" en el bloque (contigua) de espacio que desea tratar como una matriz multidimensional. "A" tiene el mismo valor que "p", pero la declaración hace que el compilador trate las referencias a "A" de la manera multidimensional que desee. Por ejemplo:

#include <iostream> 
using namespace std; 

void bar (int *p, int nz, int ny, int nx) 
{ 
    int (*A)[ny][nx] = (int(*)[ny][nx]) p; 

    for (int ii = 0; ii < nz; ii++) { 
    for (int jj = 0; jj < ny; jj++) { 
     for(int kk = 0; kk < nx; kk++) { 
      A[ii][jj][kk] = ii*1000000 + jj*1000 + kk; 
     } 
    } 
    } 
} 


void out (int *p, int nz, int ny, int nx) 
{ 
    int (*A)[ny][nx] = (int(*)[ny][nx]) p; 
    cout << A[11][22][33] << endl; 
} 


int main (void) 
{ 
    int NX = 97; 
    int NY = 92; 
    int NZ = 20; 
    int *space = new int [NZ * NY * NX]; 

    bar (space, NZ, NY, NX); 
    out (space, NZ, NY, NX); 
    return 0; 
} 

La ejecución de este produce la salida "11022033"

La declaración de la "A" alias es un poco raro mirar, pero le permite utilizar directa y simplemente la multi- deseada sintaxis de matriz dimensional

Cuestiones relacionadas