2012-01-07 9 views
3

私はC言語を学びたいと思っています。コンソールにテキストを印刷したり、ポインタを非常に単純な方法で使用したりする、小さくて簡単な例よりも高度なものを試すような気がしました。2D配列のfree()を呼び出すと、segになります。

問題が...私のプログラムは自由に私の呼び出しでクラッシュし、私はそれがポインタ(s)は何とか私を離れないで確信しているように、私はこのような2次元配列を作成している

です:

struct Grid 
{ 
    int rows; 
    int columns; 
    int **grid; 
}; 

私は、成功したプログラム全体のグリッドを使用して、すべてが素晴らしい作品:

bool InitializeGrid(struct Grid *g, int rows, int columns) 
{ 
    g->rows = rows; 
    g->columns = columns; 
    g->grid = malloc(g->rows * sizeof(int *)); 

    if(g->grid == NULL) 
    { 
     printf("Could not allocate memory for grid rows.\n"); 
     return false; 
    } 

    for (int i = 0; i < g->rows; i++) 
    { 
     g->grid[i] = malloc(g->columns * sizeof(int)); 

     if(g->grid[i] == NULL) 
     { 
      printf("Could not allocate memory for grid columns.\n"); 
      return false; 
     } 
    } 

    /.../

    return true; 
} 

構造グリッドは、次のようになります。プログラムが終了しようとしているとき、私は割り当てられたメモリを解放する必要があります。これは私がそれを行う方法です:

void CleanupGrid(struct Grid *g) 
{ 
    for(int i = 0; i < g->rows; i++) 
     free(g->grid[i]); 

    free(g->grid); 
} 

しかし、最初の空き(g-> grid [i])でセグメント化エラーが発生します。

なぜこれは機能しませんか?これをどうすれば解決できますか?

編集:

stdbool.hはBOOL /真/偽の使用のためのプログラムに含まれています。

私はfree()ステートメントで目が見えないのは本当に馬鹿だと感じます。プログラムを最小限に縮小すると、free()ステートメントでうまくいきます。私がアクセスしてグリッドに書き込むとき、free()がセグメント違反で私に挨拶します。

user1083265の回答を受け入れます。

+0

'InitializeGrid'と' CleanupGrid'を呼び出し、segfaultになる最小の 'main'関数を追加できますか?さらに、Cには 'true'や' false'といったものはありません。それらを1と0で置き換えるか、他の場所で '#define 'する必要があります。 – Jan

+0

@Jan ''、1999年以来のCの部分。 –

答えて

3

私はコードをコンパイルします(alloc/deallocだけ)、クラッシュしません。

割り当てられたグリッドを使用すると、割り当てられたフラグメントより上のメモリが破損する可能性があります。 Glibcはcanary valuesを使用してこのような破損を検出します。破損したメモリを解放するときにsegfaultを取得します。

+0

コードは私にとってもうまくいきます。 – MARK