web-dev-qa-db-fra.com

Déclarer un pointeur sur un tableau multidimensionnel et allouer le tableau

J'ai essayé de chercher mais je n'ai rien trouvé avec une réponse définitive. Je sais que mon problème ne peut pas être si difficile. Peut-être que c'est juste que je suis fatigué ..

En gros, je veux déclarer un pointeur sur un tableau à 2 dimensions. Je veux le faire de cette façon parce que je devrai éventuellement redimensionner le tableau. J'ai réussi les opérations suivantes avec un tableau 1D:

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

Je voudrais faire ce qui suit avec un tableau 2D mais cela ne compilera pas:

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

Le compilateur me donne une erreur indiquant que «une largeur» ne peut pas apparaître dans une expression constante. J'ai essayé toutes sortes de combinaisons de ** et [] [] mais aucune d'entre elles ne semble fonctionner. Je sais que ce n'est pas si compliqué ... Toute aide est la bienvenue.

21
vince88

Je viens de trouver que cette réponse ancienne est toujours lue, ce qui est dommage car elle est fausse Regardez la réponse ci-dessous avec tous les votes à la place.


Lisez la syntaxe du pointeur, vous avez besoin d’un tableau de tableaux. Ce qui est la même chose qu'un pointeur sur un pointeur.

int width = 5;
int height = 5;
int** arr = new int*[width];
for(int i = 0; i < width; ++i)
   arr[i] = new int[height];
13
dutt
const int someheight = 3;
 const int somewidth = 5;

 int (*array)[somewidth] = new int[someheight][somewidth];
42
Tony The Lion

Un exemple prêt à l'emploi de ici , après quelques secondes de googler avec l'expression "tableau dynamique à deux dimensions":

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;
6
Arun

Je suggère d'utiliser une méthode beaucoup plus simple qu'un tableau de tableaux:

#define WIDTH 3
#define HEIGHT 4

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

Je pense que c'est une meilleure approche qu'un tableau d'un tableau, car l'allocation est beaucoup moins importante. Vous pouvez même écrire une macro d'assistance:

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

int cell = array[INDEX(2,3)];
4
Alexander Rafferty

Personnellement, ma préférence est d'utiliser une astuce syntaxique pour déclarer un pointeur sur le tableau multidimensionnel dimensionné dynamiquement. Cela fonctionne dans les compilateurs qui prennent en charge les tableaux de longueur variable (VLA), que tous les compilateurs C++ devraient, et la plupart des compilateurs C actuels.

L'idée de base est capturée dans ceci:

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

"p" pointe vers le bloc d'espace (contigu) que vous voulez traiter comme un tableau multidimensionnel. "A" a la même valeur que "p", mais la déclaration demande au compilateur de traiter les références à "A" de la manière multidimensionnelle que vous voulez . Par exemple:

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

En cours d'exécution, la sortie "11022033"

La déclaration de l'alias "A" est un peu étrange, mais elle vous permet d'utiliser directement et simplement la syntaxe de tableau multidimensionnel souhaitée.

2
Bron Nelson

Je pense que ça va faire 

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

Vous pouvez entrer les valeurs en faisant quelque chose comme ça 

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