После использования функции любое последующее выделение памяти ведет к странному поведению - 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()
для выделения памяти под строку.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д