После использования функции любое последующее выделение памяти ведет к странному поведению - C (СИ)
Формулировка задачи:
После вызова функции (скрин 1) с места (скрин 2), любое последующее выделение памяти в куче, как на (скрин 3), ведет к (скрин 4). Даже если после вызова функции (скрин 1) попробовать выделить память под массив или открыть какой-то файл через fopen, то все равно будет тот же крах, который на (скрин 4). Помогите, пожалуйста, похоже, что я где-то сильно лажаю.
Решение задачи: «После использования функции любое последующее выделение памяти ведет к странному поведению»
textual
Листинг программы
#include <stdbool.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "dictionary.h"
int the_size = 0;
int *p = &the_size;
node* root = NULL;
node* getnode (void)
{
node* newNode = malloc(sizeof(node));
if (newNode != NULL)
{
newNode -> is_word = false;
for (int i = 0; i <= 28; i++)
{
newNode -> children[i] = NULL;
}
return newNode;
}
else
{
free(newNode);
return NULL;
}
}
int insert (node* root, char* word, int* p)
{
node* traverse = root;
for (int i = 0, n = strlen(word); i < n; i++)
{
int index = tolower(word[i]) - 'a';
if (traverse -> children[index] == NULL)
{
traverse -> children[index] = getnode();
if (traverse -> children[index] == NULL)
return 0;
}
traverse = traverse -> children[index];
}
traverse -> is_word = true;
*p = the_size++;
return 1;
}
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
node* findout = root;
for (int i = 0, n = strlen(word); i < n; i++)
{
if (findout -> children[(tolower(word[i]) - 'a')] == NULL)
{
return false;
}
findout = findout -> children[(tolower(word[i]) - 'a')];
}
if (findout -> is_word == true)
return true;
return false;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char* dictionary)
{
FILE* dc = fopen(dictionary, "r");
if (dc == NULL)
{
return false;
}
char* word = malloc(LENGTH+1);
root = getnode();
if (root != NULL)
{
while (fscanf(dc, "%s", word) != EOF)
{
if (insert (root, word, p) == false)
return false;
}
}
fclose(dc);
free (word);
if (root == NULL)
return false;
return true;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
int words = 0;
words = the_size;
if (words == 0)
return 0;
return words;
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
freenode(root);
return true;
}
void freenode (node* t_node)
{
for (int i = 0; i <= 27; i++)
{
if (t_node -> children[i] != NULL)
freenode (t_node -> children[i]);
}
if (t_node != NULL)
free (t_node);
}
Объяснение кода листинга программы
- Структура данных, используемая для представления словаря, это двоичное дерево.
- Функция
getnode()используется для выделения памяти под узел дерева. - Функция
insert()отвечает за добавление слова в словарь. - Функция
check()используется для проверки наличия слова в словаре. - Функция
load()загружает словарь из файла в память. - Функция
size()возвращает количество слов в словаре. - Функция
unload()используется для освобождения памяти, занятой словарем. - Функция
freenode()используется для освобождения памяти, занятой узлами дерева. - В коде используется функция
malloc()для выделения памяти под узлы дерева. - В коде используется функция
free()для освобождения памяти, занятой узлами дерева. - В коде используется функция
fscanf()для чтения слов из файла. - В коде используется функция
fclose()для закрытия файла. - В коде используется функция
free()для освобождения памяти, занятой строкой, содержащей слово. - В коде используется оператор
returnдля возврата значения из функции. - В коде используется оператор
ifдля проверки условия. - В коде используется оператор
forдля выполнения цикла. - В коде используется оператор
whileдля выполнения цикла. - В коде используется оператор
breakдля выхода из цикла. - В коде используется оператор
continueдля пропуска итерации цикла. - В коде используется оператор
malloc()для выделения памяти под строку.