2017-07-16 1 views
0

Je travaille actuellement sur un vérificateur d'orthographe (par CS5s pset5, pour ceux qui le connaissent). J'utilise un TRIE pour chercher, mais j'ai maintenant des problèmes pour le décharger. La fonction échoue la première fois qu'elle essaie de libérer(). Ma conjecture est qu'elle essaye de libérer le pointeur et non ce que pointe le pointeur, mais je pourrais me tromper complètement.Comment libérer un TRIE?

Ma question spécifique est: Pourquoi la fonction free() échoue ici? (Erreur: double libération ou la corruption (out): 0x00000000006020c0 ***)

Mon definiton d'un nœud:

typedef struct node 
{ 
    bool wordHere; 
    struct node* children[27]; 
}node; 

Ma fonction UNLOAD:

node* currentNodePtr = &root; 
bool unload(void) 
{ 
    node* ptrArray[27] = {NULL}; 

    for(int i = 0; i < 27; i++) 
    { 
     ptrArray[i] = currentNodePtr -> children[i]; 
    } 

    free(currentNodePtr); 

    for(int c = 0; c < 27; c++) 
    { 
     if(ptrArray[c] != NULL) 
     { 
      currentNodePtr = ptrArray[c]; 
     } 

     unload(); 
    } 

    return 0; 
} 
+0

Ce sera beaucoup mieux faire 'currentNodePtr' un paramètre de' unload 'à la place d'une variable globale. – interjay

+0

Malheureusement, je ne suis pas autorisé à faire cette tâche, mais cela fonctionnerait beaucoup mieux, d'accord! Merci! –

Répondre

2

Il semble que l'objet root n'a pas été alloué dynamiquement.

Le pointeur currentNodePtr ne pointe donc pas vers un objet alloué dynamiquement.

node* currentNodePtr = &root; 

Par conséquent, vous ne pouvez pas appeler

free(currentNodePtr); 

pour ce pointeur.

Vous devez allouer d'abord l'objet root dynamiquement comme n'importe quel autre noeud.

Un deuxième problème que vous devez inclure l'appel récursif de la fonction dans l'instruction if

if(ptrArray[c] != NULL) 
    { 
     currentNodePtr = ptrArray[c]; 
     unload(); 
    } 

car au début de la fonction que vous ne vérifie pas si le pointeur est égal à NULL.

Bien qu'il soit préférable au début de la fonction de vérifier que le pointeur currentNodePtr n'est pas égal à NULL.

De même, ce n'est pas une bonne idée lorsqu'une fonction utilise une variable globale. Au lieu d'utiliser la variable globale currentNodePtr en faire un paramètre de la fonction.

+0

Merci! Donc, je dois juste utiliser malloc pour créer la racine et je devrais être bon? –

+0

@MichaelKeller Oui, vous devez utiliser malloc pour créer une racine. De même, vous devez au moins inclure l'appel récursif de la fonction dans l'instruction if. –

0

Merci à tous! Le problème était que le nœud racine n'était pas alloué dynamiquement. Je ne savais pas comment je devais allouer dynamiquement la racine, donc je ce simple (mais pas très élégant) fix:

node* currentNodePtr = &root; 
bool unload(void) 
{ 
    node* ptrArray[27] = {NULL}; 

    for(int i = 0; i < 27; i++) 
    { 
     ptrArray[i] = currentNodePtr -> children[i]; 
    } 

    if(currentNodePtr != &root) 
    { 
     free(currentNodePtr); 
    } 


    for(int c = 0; c < 27; c++) 
    { 
     if(ptrArray[c] != NULL) 
     { 
      currentNodePtr = ptrArray[c]; 
      unload(); 
     } 

    } 

    return true; 
}