Извините, если следующий вопрос кажется наивным, я очень плохо знаком с программированием и все еще борюсь с основными понятиями.
Я написал код, который загружает словарь (txt файл) в хеш-таблицу / связанный списокСтруктура данных, программа компилирует и обеспечивает ожидаемые результаты, но Valgrind показывает утечки памяти.Все основные функции (создание узлов, заполнение, поиск, печать) работают нормально, кроме функции уничтожения (используется для освобождения памяти от malloc).Valgrind показывает утечки памяти.
Что мне здесь не хватает?Как сделать мой код чище?
Спасибо за ваше время!Вы великолепны!
Я знаю, что, по крайней мере, отчасти причина в моем подходе к заполнению структуры данных - я использую 2 буфера char * (tmp и tmp1, внутри и снаружи цикла) для манипулирования входами изfscanf в узлы.Я предполагаю, что во время выгрузки я могу использовать функцию «free» во внешнем буфере («tmp»), но не во внутреннем буфере («tmp1»).
Я попытался использовать 1 буфер (как внутри, так и снаружи)циклы) и 2 буфера инициализируются статически (char tmp []).Оба метода заполняют структуру всего одним словом (последнее в словаре).
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// определяют структуру узла
typedef struct node
{
char* word;
struct node* next;
}node;
// переменная размера хеш-функции и хэш-функция (спасибо,K & R)
const int hash_elements = 100;
unsigned hash(char *s)
{
unsigned hashval;
for (hashval = 0; *s != '\0'; s++)
hashval = *s + 31 * hashval;
return hashval % hash_elements;
}
// функция для добавления узла в начало ll
int addnode_start (node** head, char* word)
{
node* new_node = malloc(sizeof(node));
if (new_node == NULL)
{
return 1;
}
new_node->word = word;
new_node->next = *head;
*head = new_node;
return 0;
}
// функция для освобождения выделенной памяти
void destroy (node* hashtable)
{
if (hashtable == NULL)
{
return;
}
else
{
destroy(hashtable->next);
free(hashtable);
}
}
// MAIN FUNCTION- помещает строки слов из текстовых файлов в структуры данных хеш-таблиц / связанных списков
int main (int argc, char* argv[])
{
if (argc < 2)
{
printf("Usage: ./stringdll dictionary.txt\n");
return 1;
}
// создает массив для связанных списков (хеш-таблиц) и выделяет память для головок
node* hashtable[hash_elements];
for (int i = 0; i < hash_elements; i++)
{
hashtable[i] = malloc(sizeof(node));
if (hashtable[i] == NULL)
{
return 1;
}
}
//открыть файл словаря для чтения
char* infile = argv[1];
FILE* input = fopen(infile, "r");
if (input == NULL)
{
printf("File does not exist.\n");
return 1;
}
// определить временное хранилище для строк
char* tmp = malloc(41);
// проверить файл на наличие строк и заполнить связанные списки
while(fscanf(input, "%s", tmp) != EOF)
{
char* tmp1 = malloc(41);
for (int h = 0; h < hash_elements; h++)
{
if (hash(tmp) == h)
{
if (hashtable[h]->word == '\0')
{
hashtable[h]->word = strcpy(tmp1, tmp);
hashtable[h]->next = NULL;
}
else
{
int tmp_0 = addnode_start(&hashtable[h], strcpy(tmp1, tmp));
if (tmp_0 == 1)
{
return 1;
}
}
}
}
}
// unload Dictionary
for (int d = 0; d < hash_elements; d++)
{
destroy (hashtable[d]);
}
return 0;
}
Я ожидаю, что Valgrind покажет, что не было утечек памяти во время работы моей программы.