2016-11-17 3 views
1

je ceci:libre() un tableau de char **

struct Library { 
    char letter; 
    int capacity; 
    int size; 
    char** words; 
}; 
typedef struct Library Lib; 

Initialiser le tableau de la bibliothèque:

void InitLibrary(Program* startup) { 
    char alphabet[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; 
    startup->dictionary = malloc(sizeof(Lib) * 26); 
    int i; 
    for (i = 0; i < 26; i++) { 
     startup->dictionary[i].letter = alphabet[i]; 
     startup->dictionary[i].capacity = INIT_CAPACITY; 
     startup->dictionary[i].size = 0; 
     startup->dictionary[i].words = malloc(sizeof(char*) * startup->dictionary[i].capacity); 
    } 
} 

Ici je remplir le tableau words:

void FillDicoFromFile(Program* startup){ 
    while((!feof(startup->f) && !ferror(startup->f))){ 
     char* word = malloc(sizeof(char) * 30); 
     fscanf(startup->f, "%s", word); 
     ToLowerCase(word); 
     int indexLib = word[0] - 97; 
     int sizeLib = startup->dictionary[indexLib].size; 
     startup->dictionary[indexLib].words[sizeLib] = word; 
     startup->dictionary[indexLib].size++; 
    } 
    CountTotalWords(startup); 
    rewind(startup->f); 
} 

et une fonction comme celle-ci:

void CleanDico(Program* startup){ 
    int i = 0; 
    for(; i < startup->dictionary[i].size; i++){ 
     int j = 0; 
     for(; j < startup->dictionary[i].size; i++){ 
      free(startup->dictionary[i].words[j]); 
      startup->dictionary[i].words[j] = NULL; 
     } 
     startup->dictionary[i].size = 0; 
    } 
    startup->totalWords = 0; 
} 

J'ai obtenu la taille de mon tableau sur ma structure pour obtenir la limite de mon tableau, et libéré toutes les cellules utilisées, mais chaque fois que j'appelle CleanDico, le code se bloque. Aucune suggestion?

J'ai déjà demandé a question on a problem with a char array. Maintenant, je veux free() le tableau. J'ai lu beaucoup de posts ici et là et testé beaucoup de solutions mais aucune m'a aidé à résoudre mon problème.

Je reçois un SEGMENTATION_FAULT sur CleanDico, et je n'ai pas d'autres informations sur l'erreur. Déboguer mod sur Code :: Blocks sont pauvres avec des messages d'erreur.

+2

Nous avons besoin d'un [MCVE] ici. Le code que vous avez ici semble correct, le problème est probablement dans le code que vous n'avez pas montré. –

+0

Sur quelle ligne se plante-t-il? Quel est le message? – nicomp

+2

Vous devez publier un MCVE.Les bogues de 'malloc' sont difficiles à traquer et souvent les erreurs se produisent dans des endroits du code sans rapport avec l'endroit où se trouvent les bogues. Je suggère d'utiliser un outil comme 'valgrind' pour vous aider à trouver la source de vos problèmes. (En particulier, vous ne nous montrez jamais où vous/allouer/les chaînes dans 'words' .Vous utilisez également le même index dans votre boucle intérieure comme dans l'extérieur ...) – BadZen

Répondre

4

Je pense que votre deuxième pour vous l'intention de faire

for(; j < startup->dictionary[j].size; j++){ 

au lieu de

for(; i < startup->dictionary[i].size; i++){ 
+0

Vous n'avez pas non plus besoin d'initialiser i et j au dessus de for, en faisant 'for (int i = 0; i < startup-> dictionnaire [i] .size; i ++)' se traduira par le même. :) – user3794667384

+0

Même avec cela, le code continue de planter. et merci, je suis sûr que c'était un mauvais copier/coller ... je suis sur C89 donc ça ne marche pas ^^ – Maillful

+0

Vous devriez utiliser valgrind avec le flag -g pour pouvoir savoir quelles lignes échouent exactement, Ce sera plus facile pour nous de répondre alors! : D – user3794667384

2

Chaque malloc(), calloc() ou realloc() doit être associé à un free() correspondant (ou realloc()).

Vous avez ceci:

startup->dictionary[i].words = malloc(sizeof(char*) * N); 

Ce qui vous donne un tableau de pointeurs, initialisés (ils contiennent des déchets).

Plus tard, vous avez ceci:

free(startup->dictionary[i].words[j]); 

un pointeur qui désalloue vous n'initialisés. Et ne parvient pas à libérer ce que vous avez attribué. En outre, vous pouvez envisager une structure de données différente: allouer un grand tableau de char qui contient tous les mots, plus un tableau de char* qui contient un pointeur sur chaque mot. De cette façon, vous avez toujours exactement deux allocations et désallocations (à moins que vous ne connaissiez la taille maximale de tous vos mots, auquel cas vous pourriez avoir besoin de realloc() occasionnellement).

+0

Juste édité le message, je fais un 'malloc()' sur chaque cellule du tableau – Maillful

+0

Pour l'instant, je 'malloc()' un tableau énorme pour le débogage/test, mais quand 'CleanDico()' fonctionnera, je sera plus spécifique avec la capacité et fait 'realloc()' quand il est plein. – Maillful

1

Votre boucle for interne incrémente également la variable i. Donc ça sort de l'index.

EDIT: la boucle externe devrait fonctionner 26 fois puisque vous avez 26 lettres.

for(; i < 26; i++){ 
    int j = 0; 
    for(; j < startup->dictionary[i].size; j++){ 
     free(startup->dictionary[i].words[j]); 
     startup->dictionary[i].words[j] = NULL; 
    } 
    startup->dictionary[i].size = 0; 
} 
+0

Mon mauvais, juste un mauvais copier/coller, même avec la bonne variable, le code continue de plantage. – Maillful

+0

Pouvez-vous vérifier avec mon dernier edit – cokceken

+0

Oui, juste vu cela avant votre edit ^^, ainsi il semble que cela fonctionne, mais quand je veux charger un autre fichier et recharger le tableau, je plante. – Maillful