0

次のように定義されたグローバル 3D 配列があります。

double*** arr;  

ファイル common.c で

私は宣言を持っています

extern double*** arr;  

ファイル common.h で

実行時にこの配列を動的に初期化しているときに、コードを実行したセグメンテーション違反が発生しています

 exs =malloc(sizeof(double)*nx*ny*nz);  

ここで、nx、ny、および nz は、このステートメントを実行する前に実行時に認識されます。

しかし、この配列を次のように初期化しようとすると

  for(i=0;i<nx;i++)  
      for(j=0;j<ny;j++)  
          for(k=0;k<nz;k++)  
              arr[i][j][k]=0.0e0;  

セグメンテーション違反が発生します。

私は何を間違っていますか?

4

2 に答える 2

7

すべての次元を割り当てる必要があります:

arr = malloc(sizeof(*arr) * nx);
for (int i = 0; i < nx; i++)
{
    arr[i] = malloc(sizeof(**arr) * ny);
    for (int j = 0; j < ny; j++)
    {
        arr[i][j] = malloc(sizeof(***arr) * nz);
        for (int k = 0; k < nz; k++)
        {
            arr[i][j][k] = 0.0;
        }
    }
}

そしてもちろん、割り当てたすべてのデータを解放することを忘れないでください。

于 2013-06-28T06:51:24.523 に答える
6

まず、配列はポインタではありません

次に、メモリの断片化を回避し、関数への 1 回の呼び出しを使用する別のソリューションを紹介しますmalloc()(これはコストがかかります)。

double (*arr)[ny][nz] = malloc(sizeof(*arr) * nx);

arrこの後、次元の配列として使用できますnx * ny * nz

これをファイル スコープで使用する場合: として宣言しvoid *、要素にメモリをnx * ny * nz割り当ててから、便宜上使用するときに配列へのポインタに割り当てます。

// common.h
extern void *ptr;

// common.c
ptr = malloc(sizeof(double) * nx * ny * nz);

// foo.c
double (*arr)[ny][nz] = ptr;

しかし、そのようなハックが必要な場合は...自分が何を間違えたかを考えるべきです。この場合、1 つ間違ったことをしています。グローバル変数を使用しています。使用しないでください。

于 2013-06-28T06:54:25.443 に答える