1

I have this :

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

Initialize the array of Library:

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

Here i populate the array 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);
}

and a function like this :

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

I got the size of my array on my struct to get the limit of my array, and freed all used cells, but each time I call CleanDico, the code crashes. Any suggestions?

I've already asked a question on a problem with a char array. Now I want to free() the array. I've read plenty of posts here and there and tested a lot of solutions but none helped me to resolve my problem.

I get a SEGMENTATION_FAULT on CleanDico, and I don't have any other informations about the error. Debug mod on Code::Blocks are poor with error messages.

Community
  • 1
  • 1
Maillful
  • 77
  • 1
  • 6
  • 2
    We need an [MCVE] here. The code you shbow here looks OK, the problem is most likely in the code you didn't show. – Jabberwocky Nov 17 '16 at 13:26
  • What line does it crash on ? What is the message? – nicomp Nov 17 '16 at 13:29
  • 2
    You need to post an MCVE. `malloc` bugs are difficult to track down and often the errors happen in places in the code unrelated to where the bugs are. I suggest using a tool like `valgrind` to help find the source of your problems. (In particular, you never show us where you /allocate/ the strings in `words`. Also, you're using the same index in your inner loop as in the outer...) – BadZen Nov 17 '16 at 13:30
  • Why do you have a double loop of "i". Shouldn't the inner be "j"? – Elad Weiss Nov 17 '16 at 13:30
  • Just edited the post, wrong copy/paste – Maillful Nov 17 '16 at 13:54
  • What happens when you remove startup->dictionary[i].words[j] = NULL; – cokceken Nov 17 '16 at 14:08
  • Nothing, code keeps crashing. – Maillful Nov 17 '16 at 14:17

3 Answers3

4

I think on your second for you meant to do

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

instead of

for(; i < startup->dictionary[i].size; i++){
user3794667384
  • 437
  • 7
  • 23
2

Every malloc(), calloc(), or realloc() must be matched with a corresponding free() (or realloc()).

You have this:

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

Which gives you an array of pointers, uninitialized (they contain garbage).

Later you have this:

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

Which deallocates a pointer you never initialized. And fails to deallocate what you allocated.

As an aside, you may wish to consider a different data structure: allocate one huge array of char which contains all words, plus one array of char* which contains one pointer to each word. This way you always have exactly two allocations and deallocations (unless you don't know the maximum size of all your words, in which case you might need to realloc() occasionally).

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Just edited the post, i do a `malloc()` on each cells of the array – Maillful Nov 17 '16 at 13:47
  • For now, i `malloc()` a huge array for the debug/test, but when `CleanDico()` will works, i will be more specific with the capacity and do `realloc()` when it's full. – Maillful Nov 17 '16 at 14:07
1

Your inner for loop also increments i variable. So it goes out of index.

EDIT: outer loop should run for 26 times since you have 26 letter.

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;
}
cokceken
  • 2,068
  • 11
  • 22
  • My bad, just a bad copy/paste, even with the good variable, the code keep crashing. – Maillful Nov 17 '16 at 13:49
  • Yes, just saw that before your edit ^^, so it looks like it works, but when i want load an another file and refill the array, i crash. – Maillful Nov 17 '16 at 15:10