2016-07-17 8 views
0

Iはdriver.hにおいてそのようなものとして初期化3Dダブル配列を有する:Cヘッダファイルに定義されたのcalloc 3Dアレイ、無効な読み取りエラー

extern double ***grid; 

をIはdriver.cにその値を設定したい:

double ***grid; 
grid = calloc(cells_x * cells_y * cells_z, sizeof(double)); 
grid[0][1][2] = 123; 

ただし、valgrindは「無効なサイズ8の読み取り」エラーを示します。私は間違って何をしていますか?

+0

'grid.c'を' driver.c'のグローバルとして宣言しましたか? – Kninnug

+0

'double *** grid;'は、その言語に関する3d配列ではありません。 – StoryTeller

+0

[this](http://stackoverflow.com/questions/14111210/when-two-dimensional-array-and-multidimensional-array-as-function-parameters-in/14111286#14111286) – StoryTeller

答えて

5

あなたのコードは、ポインター(アスタリスクの3つの配列)へのポインターの配列を宣言していますが、割り当てによって、サイズがcells_x * cells_y * cells_zの単一ブロックへのポインターが配置されます。 - 複数のループで

static double*** initGrid(size_t cells_x, size_t cells_y, size_t cells_z) { 
    double ***grid; 
    grid = malloc(cells_x, sizeof(double**)); 
    for (size_t x = 0 ; x != cells_x ; x++) { 
     grid[x] = malloc(cells_y, sizeof(double*)); 
     for (size_t y = 0 ; y != cells_y ; y++) { 
      grid[x][y] = calloc(cells_z, sizeof(double)); 
     } 
    } 
    return grid; 
} 
static void freeGrid(double ***grid, size_t cells_x, size_t cells_y) { 
    for (size_t x = 0 ; x != cells_x ; x++) { 
     for (size_t y = 0 ; y != cells_y ; y++) { 
      free(grid[x][y]); 
     } 
     free(grid[x]); 
    } 
    free(grid); 
} 

あなたは別の方法でジャグ配列を割り当て、自由にする必要があります:あなたのextern変数のユーザーは「ギザギザ」の配列(ポインタへのポインタのすなわち配列)を期待するので、これは、間違っています配列の配列へのポインタとしてgridを宣言してください。

+0

ありがとうございました!それは機能しました(mallocはcells_x * sizeofです)。時間がある場合は、例えば、これを関数内に配置して、このようなものを別のファイルに「隠す」ようにして、initGrid(grid、cells_x、cells_y、cells_z)メインの方法で? –

+0

@DarbininkaiBroliai確かに - 私はグリッドを初期化して解放するための機能を作るように編集しました。初期化関数はポインタを設定するのではなく、ポインタを返します。なぜなら、パラメータとして4つのアスタリスクポインタを使うことが考えられるからです(変更のために '&grid'を渡す必要があります)。 – dasblinkenlight

関連する問題