2016-10-14 2 views
0

J'essaie d'utiliser une liste chaînée de structures dans C, avec une structure représentant la liste et une autre représentant les membres de la liste. C'est leur définition:Erreurs d'exécution lors de l'utilisation de Free() dans C

typedef struct symEntry symEntry; 

struct symEntry{ 
    const char * key; 
    const void * value; 
    struct symEntry * next; 
    struct symEntry * linked; 
    struct symEntry * previous; 
}; 

typedef struct{ 
    symEntry* head; 
    symEntry* tail; 
    int size; 
} symTab; 

typedef symTab * SymTab; 

Et mon problème est quand j'essaie de libérer la mémoire que j'alloue. J'allouez tout cela et revenir struct de la liste comme ceci:

SymTab ST_new() 
{ 
    SymTab oSymTab = (SymTab)malloc(sizeof(SymTab)); 

    symEntry * head = (symEntry *)malloc(sizeof(symEntry)); 
    head->key = NULL; 
    head->value = NULL; 
    head->previous = NULL; 
    head->linked = NULL; 

    oSymTab->head = head; 
    oSymTab->size = 0; 

    ST_fill(oSymTab, sizeArray[currentSize]); 
    return oSymTab; 
} 

void ST_fill(SymTab oSymTab, int size) 
{ 
    symEntry * current; 
    current = oSymTab->head; 
    int i; 
    for(i = 0; i < size-1; i++) 
    { 
     symEntry * entry = (symEntry *)malloc(sizeof(symEntry)); 
     entry->key = NULL; 
     entry->value = NULL; 

     entry->linked = NULL; 
     entry->previous = current; 
     current->next = entry; 
     current = current->next; 
    } 

    current->next = NULL; 
    oSymTab->tail = current; 
} 

Ainsi, initialisant la tête et initialisant alors tous les éléments en fonction de la taille que je veux que la liste soit. Définissez next et previous, de sorte que previous soit null au début et next soit null à la fin. Mon problème commence vraiment lorsque je tente de libérer la mémoire dans une fonction séparée après qu'il a été utilisé:

void ST_free(SymTab oSymTab) 
{ 
    symEntry * current; 
    symEntry * previous; 
    current = oSymTab->head; 

    while(current->next != NULL) 
    { 
     previous = current; 
     current= current->next; 
     free(previous); 
    } 

    free(oSymTab); 
} 

Si je commente sur les déclarations gratuitement le code fonctionne sans problème (j'ai couru des opérations sur le struct après le remplissage avec des valeurs vides et il a zéro problème), donc cette configuration n'a pas de problèmes jusqu'à ce que j'essaie de libérer la mémoire. J'ai parfois des erreurs d'exécution, peut-être 50% du temps.

Je n'ai vraiment aucune idée de ce que le problème est, en particulier lorsque le code s'exécute sans problème à certains moments et échoue à d'autres. Est-ce que quelqu'un pourrait me guider?

+2

S'il vous plaît poster a [MCVE] –

+0

Devrions-nous * deviner * ce qu'est un 'SymTab' (par opposition à un' symTab')? – WhozCraig

+1

Vous devez produire un exemple complet; quelque chose que nous pouvons compiler et exécuter, et voir l'erreur se produire. Il est probable que le problème ne soit pas dans le code que vous avez publié. – davmac

Répondre

2

Vous devez vérifier les pointeurs NULL avant d'accéder à libérer la mémoire pointée.

void ST_free(SymTab oSymTab) 
{ 
    if (oSymTab != NULL) 
    { 
     symEntry * current; 
     symEntry * previous; 
     current = oSymTab->head; 

     while(current != NULL && current->next != NULL) 
     { 
      previous = current; 
      current= current->next; 
      free(previous); 
     } 
     free(oSymTab); 
    } 
} 

Vous devriez également vérifier que les appels malloc ne retournent pas la valeur NULL.

+0

Cela a fonctionné, merci beaucoup. –

0
SymTab oSymTab = (SymTab)malloc(sizeof(SymTab)); 

Vous devez utiliser un pointeur struct:

SymTab *oSymTab = (SymTab *)malloc(sizeof(SymTab)); 

Tous votre code sont l'utilisation symtab, les remplacer par des symtab *

+0

Ce n'est pas une réponse. –

+0

J'ai utilisé typedef symTab * SymTab; pour résoudre le problème du pointeur. Je vais ajouter cela au post principal, j'ai oublié à ce sujet. –

0

Alors ... d'abord je vais coller tous vos code corrigé et après que je vous marquerons quelques erreurs:

#include <stdlib.h> 

typedef struct symEntry symEntry; 

struct symEntry{ 
    const char * key; 
    const void * value; 
    struct symEntry * next; 
    struct symEntry * linked; 
    struct symEntry * previous; 
}; 

typedef struct{ 
    symEntry* head; 
    symEntry* tail; 
    int size; 
} symTab; 

void ST_fill(symTab * oSymTab, int size) 
{ 
    symEntry * current; 
    current = oSymTab->head; 

    for(int i = 0; i < size-1; i++) 
    { 
     symEntry * entry = (symEntry *)malloc(sizeof(symEntry)); 
     entry->key = NULL; 
     entry->value = NULL; 

     entry->linked = NULL; 
     entry->previous = current; 
     current->next = entry; 
     current = current->next; 
    } 

    current->next = NULL; 
    oSymTab->tail = current; 
} 

symTab ST_new() 
{ 
    symTab * oSymTab = malloc(sizeof(symTab)); 

    int currentSize = 1; 
    int sizeArray[currentSize]; 

    symEntry * head = (symEntry *)malloc(sizeof(symEntry)); 
    head->key = NULL; 
    head->value = NULL; 
    head->previous = NULL; 
    head->linked = NULL; 

    oSymTab->head = head; 
    oSymTab->size = 0; 

    ST_fill(oSymTab, sizeArray[currentSize]); 
    return * oSymTab; 
} 

void ST_free(symTab * oSymTab) 
{ 
    symEntry * current; 
    symEntry * previous; 
    current = oSymTab->head; 

    while(current->next != NULL) 
    { 
      previous = current; 
      current= current->next; 
      free(previous); 
    } 

    free(oSymTab); 
} 
  • Vous ai mistype certaines variables (symtab -> symtab)
  • Certaines de ces variables sont nécessaires pour être des pointeurs
  • Et certains d'entre eux étaient des paramètres devaient être inclus dans la tête de votre fonction
+0

Et free() a besoin d'un pointeur (identique à celui d'un malloc). Donc, dans la tête de votre fonction ST_free(), vous devez mettre un paramètre pointeur, pas un simple paramètre variable. –

+0

J'ai oublié de mettre cela dans le message principal, j'ai cette ligne –

+0

typedef symTab * SymTab; (affiché accidentellement) donc SymTab correspond à symTab * essentiellement. Cela devrait-il résoudre le premier problème que vous avez eu? Je vais réparer les autres maintenant. –