2010-10-11 12 views
18

Ho provato a cercare ma non ho trovato nulla con una risposta definitiva. So che il mio problema non può essere così difficile. Forse è solo che sono stanco ..Dichiarare un puntatore all'array multidimensionale e allocare l'array

Fondamentalmente, voglio dichiarare un puntatore a un array bidimensionale. Voglio farlo in questo modo perché alla fine dovrò ridimensionare l'array. Ho fatto quanto segue con successo con una serie 1D:

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

Vorrei fare quanto segue con una matrice 2D, ma non si compila:

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

Il compilatore mi dà un errore che indica che "in qualche modo" non può apparire in un'espressione costante. Ho provato tutti i tipi di combinazioni di ** e [] [] ma nessuno di loro sembra funzionare. So che non è così complicato ... Qualsiasi aiuto è apprezzato.

risposta

12

Ho appena scoperto che questa antica risposta viene ancora letta, il che è un peccato dato che è sbagliato. Guarda invece the answer below con tutti i voti.


Leggere sulla sintassi del puntatore, è necessario un array di matrici. Qual è la stessa cosa di un puntatore a un puntatore.

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

Hai provato questo? Non si compila (se altezza e larghezza sono entrambe variabili) –

+0

Sì, ho provato questo e ancora ottenere lo stesso errore con il compilatore. dirà che "larghezza" non può apparire in un'espressione costante " – vince88

+1

Se dovessi accedere a un elemento di questo array, sarebbe solo arr [larghezza] [altezza]? – vince88

5

Un pronto per l'uso ad esempio da here, dopo pochi secondi di googling con la frase "due array dinamico dimensionale":

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

Questa è una matrice di matrici, non proprio 2D. –

+3

@Alexander Rafferty: Vedo - qual è la differenza tra "array di array" e "array 2D"? – Arun

+5

@ArunSaha, questo è vecchio, ma per rispondere alla tua domanda e per chiunque altro inciampi in questo, un 2- L'array D è contiguo in memoria, una matrice dinamica di array dinamici è contigua nella prima dimensione, ma ogni array nella seconda dimensione è memorizzato separatamente –

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

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

A differenza delle altre risposte qui, questo in realtà risponde alla domanda, ovvero come dichiarare un puntatore a un array multidimensionale, non a un array scalettato. Questa è una differenziazione importante per le applicazioni sensibili alle prestazioni. Funziona se "in qualche modo" è una costante e cambia solo "un'altezza". Se si guarda a come questo array 2D è disposto in memoria - è tutto insieme e contiguo, con nient'altro che la singola "nuova" allocazione di memoria fatta. La risposta di Alexander Rafferty è anche buona se la larghezza è anche dinamica. Le altre risposte sono lente perché fanno un sacco di malloc ... –

4

Io suggerisco di usare un metodo molto più semplice di una serie di array:

#define WIDTH 3 
#define HEIGHT 4 

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

credo che questo è un approccio migliore di una matrice di una matrice, in quanto v'è fa r meno allocazione. Si potrebbe anche scrivere una macro aiutante:

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

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

Penso che questo farà

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

È possibile inserire i valori di fare qualcosa di simile

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

Personalmente, la mia preferenza è quella di utilizzare un trucco sintattico per dichiarare un puntatore all'array multidimensionale di dimensioni dinamiche. Funziona in compilatori che supportano Array di variabili (VLA), che devono essere compilati da tutti i compilatori C++ e dai compilatori C più attuali.

L'idea di base è catturato in questo:

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

punti "P" al blocco (contigua) di spazio che si desidera trattare come un array multi-dimensionale. "A" ha lo stesso valore di "p", ma la dichiarazione fa sì che il compilatore tratti i riferimenti a "A" nel modo multidimensionale desiderato. Per esempio:

#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; 
} 

L'esecuzione di questo produce l'uscita "11.022.033"

La dichiarazione della "A" alias è un po 'strano guardare, ma ti permette direttamente e semplicemente utilizzare per il multi desiderato sintassi di array dimensionale

Problemi correlati