0

Je suis sûr que vous (les pros) pouvez identifier le bug 'dans mon code, j'apprécierais également tous les autres commentaires sur mon code.Bogue d'allocation de mémoire dynamique simple

BTW, le code se bloque après l'avoir exécuté.

#include <stdlib.h> 
#include <stdio.h> 
#include <stdbool.h> 

typedef struct 
{ 
    int x; 
    int y; 
} Location; 

typedef struct 
{ 
    bool walkable; 
    unsigned char walked; // number of times walked upon 
} Cell; 

typedef struct 
{ 
    char name[40]; // Name of maze 
    Cell **grid; // 2D array of cells 
    int rows;  // Number of rows 
    int cols;  // Number of columns 
    Location entrance; 
} Maze; 


Maze *maz_new() 
{ 
    int i = 0; 

    Maze *mazPtr = (Maze *)malloc(sizeof (Maze)); 

    if(!mazPtr) 
    { 
     puts("The memory couldn't be initilised, Press ENTER to exit"); 
     getchar(); 
     exit(-1); 
    } 
    else 
    { 
     // allocating memory for the grid 
    mazPtr->grid = (Cell **) malloc((sizeof (Cell)) * (mazPtr->rows)); 

    for(i = 0; i < mazPtr->rows; i++) 
     mazPtr->grid[i] = (Cell *) malloc((sizeof (Cell)) * (mazPtr->cols)); 
    } 

    return mazPtr; 
} 


void maz_delete(Maze *maz) 
{ 
    int i = 0; 

    if (maz != NULL) 
     { 
      for(i = 0; i < maz->rows; i++) 
       free(maz->grid[i]); 

      free(maz->grid); 
     } 
} 


int main() 
{ 
    Maze *ptr = maz_new(); 
    maz_delete(ptr); 

    getchar(); 
    return 0; 
} 

Merci d'avance.

+0

Pourquoi consacrez-vous pas la grille aller? par exemple. maxPtr-> grille = malloc (sizeof (Cell) * mazPtr-> lignes * mazPtr-> cols); Je trouve que l'accès aux cellules comme celui-ci est conceptuellement plus simple. –

Répondre

0

Quelle est la taille du labyrinthe? Vous n'initialisez jamais rows et cols.

Votre gros problème, cependant, est que vous utilisez sizeof (Cell) lors de l'initialisation grid, mais il devrait être sizeof (Cell *).

Sur mon architecture, Cell est seulement deux octets, alors que Cell * est huit octets, ce qui signifie que vous n'avez pas alloué suffisamment d'espace. Lorsque vous remplissez ce tableau, vous écrivez au-delà de la fin et dans un autre morceau de mémoire allouée, à quel point tous les paris sont désactivés. L'allocateur de mémoire corrompt le contenu du tableau à un certain point, et il vous reste à essayer de libérer les déchets.

+0

Oh shoot, je suppose que j'ai oublié cette partie:/ De toute façon, je mets un (10) au lieu des rangs et des cols, mais ça ne marche toujours pas. La chose étrange est, comment se fait-il que le compilateur n'ait pas reconnu que les lignes, les cols n'étaient pas initialisés. Aussi le même code ne s'est même pas écrasé sur un autre compilateur!?. – m4design

+1

Il est impossible pour le compilateur de détecter les variables non initialisées dans le cas général, puisqu'il est équivalent au problème d'arrêt. Il ne s'est pas écrasé sur un autre compilateur car les valeurs sont indéterminées. Ils peuvent être 0, -1, un nombre aléatoire ou n'importe quoi. Des compilateurs différents, des versions différentes d'un compilateur et même des exécutions différentes du même programme peuvent donner des résultats différents. –

+0

Aha, j'ai compris, merci beaucoup. Avez-vous identifié l'autre bogue à l'origine du plantage? – m4design

1

En plus du problème Marcelo a, je repéré ceci:

mazPtr->grid = (Cell **) malloc((sizeof (Cell)) * (mazPtr->rows)); 

Vous allouons 10 cellules, ce renvoie un pointeur sur la première cellule, ce qui serait de type Cell *. Une structure Cell est une bool et une unsigned char, ce qui, en fonction de l'architecture du compilateur et de la cible, peut ne pas être suffisamment grande pour contenir un Cell * (qui peut être un pointeur de 64 bits). Lorsque vous initialisez votre tableau de grille plus tard, vous finissez probablement par écrire au-delà des extrémités du tableau. Donc, essayez d'allouer 10 sizeof (Cell *) dans votre grille. Et régler le problème d'initialisation là bien sûr.

0

à maz_delete vous avez besoin d'un autre appel à libérer pour la structure elle-même MAZ

vide de maz_delete (Maze * MAZ) {int i = 0;

if (maz != NULL) 
{ 
    for(i = 0; i < maz->rows; i++) 
     free(maz->grid[i]); 

    free(maz->grid); 

    free(maz); 
} 

}