2017-12-09 3 views
0

Hier ist mein Code, ich bekomme einen Segmentierungsfehler und ich weiß nicht warum ... Ich erstelle ein Gitter, das n ist seine Größe, tab ist ein Array, das sein Typ Zelle ist: eine Zelle hat 2 Werte. Also erstelle ich in der Funktion creer_grille ein Array I malloc es (Größe kann 4 6 oder 8 sein) und initialisiere ich die Zellenwerte mit -1 und 0. Dann teste ich in der folgenden Funktion die creer_grille Funktion. Warum segfault ich?

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

Wahrscheinlich wollen Sie: 'assert ((n == 4 || n == 6 || n == 8) &&" Breite des Gitters different de 4,6 oder 8 ");' – wildplasser

Antwort

3
g->n = n; 

Dies ist ein uninitalized Wert Zugriff - Undefined Behavior in Ihrem Code aufrufen. Verschieben Sie die Zeile nach dem Zuweisen unter Verwendung von malloc.

Auch g = malloc(sizeof(int) * (n*n)); ist falsch Sie wollen grille* nicht auf einen Chunk zeigen, der für int 's zugeordnet ist. weil, falls nicht genügend Speicher vorhanden ist, wird es ein undefiniertes Verhalten geben, das Speicher aus Ihrer Zuweisung herausholt.

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

Wie Sie die n*n Standorten zugewiesen haben für grille speichern Sie sie

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

Wieder g->tab[i].val = -1; das ist falsch, weil aus dem gleichen Grund bereits erwähnt. Sie müssen Speicher g[i].tab zuweisen. Ansonsten ist es undefiniertes Verhalten. Sie müssen Speicher für g[i].tab reservieren.

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

Auch gibt es einen Fehler in Ihrer Logik. Zuallererst Zuteilung nxn Speicher bedeutet nicht, dass Sie nxn Grid haben. Die Methode, die Sie befolgt haben, gibt Ihnen einen zusammenhängenden Teil von nxn Elementen, die nicht von dieser Verwendung sind. (Sie können es nutzen, aber das ist ein Overkill).

Das beste, was Sie tun können, ist ein gezacktes Array und das Beispiel wird hier gezeigt.

Beispielcode: -

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

Sie müssen free die dynamisch zugewiesenen Speicher, nachdem Sie mit ihm getan arbeiten. Die free Logik wäre etwas wie - Sie werden zuerst den Speicher freigegeben in tab freigeben und dann, nachdem alle diese Speicher freigegeben ist, werden Sie Speicher freigegeben in g freigeben.