web-dev-qa-db-ja.com

多次元配列へのポインターを宣言し、配列を割り当てる

私は探してみましたが、決定的な答えを見つけることができませんでした。私の問題はそれほど難しくないことを知っています。たぶん私は疲れているだけだ.

基本的に、2次元配列へのポインターを宣言します。最終的には配列のサイズを変更する必要があるため、この方法でやりたいと思います。 1D配列で次のことを正常に完了しました。

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

2D配列で次のことをしたいのですが、コンパイルされません:

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

コンパイラーは、「somewidth」を定数式に含めることができないというエラーを表示します。 **と[] []のあらゆる組み合わせを試しましたが、どれも機能していないようです。私はこれがそれほど複雑ではないことを知っています...どんな助けも感謝します。

22
vince88

私はちょうどこの古代の答えがまだ読まれるのを見つけました。それは間違っているので残念です。代わりに、すべての投票で 以下の回答 を見てください。


ポインタ構文を読んで、配列の配列が必要です。これは、ポインターへのポインターと同じものです。

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];
44
Tony The Lion

here のすぐに使用できる例を、「2次元の動的配列」というフレーズで数秒間グーグルで調べた後:

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

配列の配列よりもはるかに単純な方法を使用することをお勧めします。

#define WIDTH 3
#define HEIGHT 4

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

割り当てがはるかに少ないため、これは配列の配列よりも優れたアプローチだと思います。ヘルパーマクロを作成することもできます。

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

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

個人的には、私の好みは、動的なサイズの多次元配列へのポインターを宣言するための構文トリックを使用することです。これは、すべてのC++コンパイラが必要とする可変長配列(VLA)をサポートするコンパイラ、および最新のCコンパイラで機能します。

基本的な考え方は次のとおりです。

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

「p」は、多次元配列として扱うスペースの(連続した)ブロックを指します。 「A」は「p」と同じ値ですが、宣言により、コンパイラは「A」への参照を多次元的に処理します。例えば:

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

これを実行すると、出力「11022033」が生成されます

「A」エイリアスの宣言は少し奇妙に見えますが、目的の多次元配列構文を直接かつ単純に使用することができます

2
Bron Nelson

これでいいと思う

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

このようなことをすることで値を入力できます

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