2017-12-09 21 views
0

ここに私のコードはありますが、私はセグメンテーションフォルトが発生しています。理由はわかりません。 tabは、彼のタイプがcelluleの配列です:セルには配列がありますnのグリッドを作成しています2値。だから私は関数creer_grille私はそれは(サイズは4 6または8にすることができます)を作成していると私は-1と0でセルの値を初期化します。次に、私はcreer_grille関数をテストしています。なぜsegfaultですか?

typedef struct 
{ 
    int val; 
    int initial; 
} cellule; 

typedef struct 
{ 
    cellule *tab; 
    int  n; 
} grille; 

grille *creer_grille(int n) 
{ 
    grille *g; 
    int i; 

    assert(n == 4 || n == 6 || n == 8 && "Taille de la grille différent de 4,6 ou 8"); 
    g->n = n; 
    g = malloc(sizeof(int) * (n*n)); 
     if (g->tab == NULL) 
       exit(-1); 
    for (i = 0; i < n*n; i++) 
     { 
     g->tab[i].val = -1; 
     g->tab[i].initial = 0; 
     } 
     return g; 
} 

void detruire_grille(grille * g) 
{ 
    free(g); 
} 

void test_creer_grille(){ 
    int i,k; 
    for(k = 4; k <= 8 ; k+=2){ 
     grille * g = creer_grille(k); 
     assert(g->n == k && "Problème dans le champ n de la grille"); 

     //Vérification que les cellules sont vides 
     for(i = 0 ; i < k * k ; i++){ 
      assert(g->tab[i].val == -1 && "Problème : cellule non vide !"); 
      assert(g->tab[i].initial == 0 && "Problème : cellule initiale !"); 
     } 
     detruire_grille(g); 
    } 
    printf("Test de la fonction creer_grille OK !\n"); 
} 

int main() 
{ 
    test_creer_grille(); 
} 
+0

'assert((n == 4 || n == 6 || n == 8)&&" Taille de la grilledifférentde 4,6 ou 8 "); – wildplasser

答えて

3
g->n = n; 

これはuninitalized値にアクセスしている - あなたのコードでUndefined Behaviorを呼び出します。 mallocを使用して割り当てた後に行を移動します。

また、grille*は、intのために割り当てられたチャンクを指してはいけません。十分なメモリがない場合は、割り当てからメモリを解放する未定義の動作があるためです。あなたは同じ理由は、以前の指摘であるため、これは間違っているアゲインg->tab[i].val = -1;

 for (i = 0; i < n; i++) 
     { 
     // for some x 
     g[i].tab[x].val = -1; 
     g[i].tab[x].initial = 0; 
     } 

にインデックスを付けることで、あなたがそれらにアクセスする必要があり grilleを格納するための n*n場所を割り当てられてきたように

g = malloc(sizeof(*g) * (n)); 

。メモリをg[i].tabに割り当てる必要があります。それ以外の場合は、未定義の動作です。 g[i].tabのメモリを割り当てる必要があります。

g[i].tab = malloc(sizeof *g[i].tab * someSize); 

また、ロジックに欠陥があります。まず、nxnメモリを割り当てても、グリッドがnxnになっているわけではありません。あなたが従ったメソッドは、nxn要素の連続したチャンクを与え、それはそのようには使用されません。 (あなたはそれを利用することができますが、それは過剰です)。

あなたが行うことができる最も良いことは、ギザギザの配列であり、その例がここに示されています。

コード例: -

grille *creer_grille(int n) 
{ 
    grille *g; 

    g = malloc(sizeof *g * n); 
    if(g == NULL){ 
    fprintf(stderr,"%s\n","Error in malloc"); 
    exit(1); 
    } 

    for (size_t i = 0; i < n; i++) 
    { 
    g[i].tab = malloc(sizeof *g[i].tab * n); 
    if(g[i].tab == NULL){ 
     fprintf(stderr, "%s\n", "Error in malloc"); 
     exit(1); 
    } 
    g[i].n = n; 
    for(size_t j = 0; j < n; j++){ 
     g[i].tab[j].val = -1; 
     g[i].tab[j].initial = 0; 
    } 
    } 
    return g; 
} 

あなたはfreeにあなたがそれで作業が完了した後、動的に割り当てられたメモリを持っています。 freeのロジックは、最初にtabに割り当てられたメモリを解放し、それらのメモリがすべて解放された後に、gに割り当てられたメモリを解放します。

関連する問題