2016-11-17 3 views
1

У меня есть это:бесплатно() массив гольца **

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

Инициализировать массив библиотеки:

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

Здесь я заселить массив 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); 
} 

и такая функция:

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

Я получил размер моего массива в своей структуре, чтобы получить предел моего массива, и освободил все используемые ячейки, но каждый раз, когда я вызываю CleanDico, код падает. Какие-либо предложения?

Я уже спросил a question on a problem with a char array. Теперь я хочу free() массив. Я читал много сообщений здесь и там и тестировал множество решений, но ни один из них не помог мне решить мою проблему.

Я получаю SEGMENTATION_FAULT на CleanDico, и у меня нет никакой другой информации об ошибке. Отладочный мод по коду :: Блоки с ошибками.

+2

Здесь необходимо [MCVE]. Код, который вы видите, выглядит хорошо, проблема, скорее всего, в коде, который вы не показывали. –

+0

В какой строке он падает? Что такое сообщение? – nicomp

+2

Вам необходимо разместить MCVE.Ошибки 'malloc' трудно отследить, и часто ошибки происходят в местах кода, не связанных с ошибками. Я предлагаю использовать инструмент, например 'valgrind', чтобы помочь найти источник ваших проблем. (В частности, вы никогда не показываете нам, где вы/выделяете/строки в словах. Кроме того, вы используете тот же индекс в своем внутреннем цикле, что и во внешнем ...) – BadZen

ответ

4

Я думаю, что на вашем секунду вы имели в виду, чтобы сделать

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

вместо

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

Вам также не нужно инициализировать i и j над параметром for, делая 'for (int i = 0; i < startup-> словарь [i] .size; i ++)' приведет к тому же. :) – user3794667384

+0

Даже при этом код продолжает сбой. и спасибо, я уверен, что это была неправильная копия/вставка ... я на C89, поэтому он не работает ^^ – Maillful

+0

Вы должны использовать valgrind с флагом -g, чтобы вы могли узнать, какие строки точно терпят неудачу, это нам будет легче ответить тогда! : D – user3794667384

2

Каждый malloc(), calloc() или realloc() должны быть согласованы с соответствующим free() (или realloc()).

У вас есть это:

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

Что дает вам массив указателей, инициализируется (они содержат мусор).

Позже у вас есть это:

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

Который освобождает указатель вы никогда не инициализирована. И не удается освободить то, что вы выделили.

В качестве альтернативы вы можете рассмотреть другую структуру данных: выделить один огромный массив из char, который содержит все слова, плюс один массив из char*, который содержит по одному указателю на каждое слово. Таким образом, вы всегда имеете ровно два распределения и освобождения (если вы не знаете максимальный размер всех ваших слов, в этом случае вам может понадобиться realloc()).

+0

Только что отредактировал сообщение, я делаю 'malloc()' в каждой ячейке массива – Maillful

+0

. Теперь i 'malloc()' огромный массив для отладки/теста, но когда 'CleanDico()' будет работать, i будет более конкретным с емкостью и сделать 'realloc()' когда он будет заполнен. – Maillful

1

Ваш внутренний цикл цикла также увеличивает значение переменной i. Таким образом, он выходит из индекса.

EDIT: внешний контур должен работать 26 раз, так как у вас есть 26 букв.

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

Мой плохой, просто плохая копия/вставка, даже с хорошей переменной, код продолжает сбой. – Maillful

+0

Можете ли вы проверить с моим последним правлением – cokceken

+0

Да, только что увидел, что перед вашим редактированием ^^, так что похоже, что он работает, но когда я хочу загрузить другой файл и пополнить массив, я сбой. – Maillful

Смежные вопросы