Я работаю над двусвязным списком. Вот код:
#include <malloc.h>
#include <stdio.h>
#include "Node.h"
Node* CreateNode(void *data)
{
Node* nNode = (Node*)malloc(sizeof(Node));
nNode->data = data;
nNode->prev = NULL;
nNode->next = NULL;
return nNode;
}
List* CreateList()
{
List* nList = (List*)malloc(sizeof(List));
nList->head = NULL;
nList->tail = NULL;
nList->current = NULL;
return nList;
}
void Last(List* list, void *data)
{
Node* nNode = CreateNode(data);
if (list->head == NULL)
{
list->head = nNode;
return;
}
else if (list->head->next == NULL)
{
list->tail = nNode;
list->head->next = list->tail;
list->tail->prev = list->head;
return;
}
else
{
list->current = list->tail;
list->tail = nNode;
list->tail->prev = list->current;
list->current->next = list->tail;
return;
}
}
void First(List* list, void *data)
{
Node* nNode = CreateNode(data);
if (list->head == NULL)
{
list->head = nNode;
}
else if (list->head->next == NULL)
{
list->tail = list->head;
list->head = nNode;
list->head->next = list->tail;
list->tail->prev = list->head;
}
else
{
list->current = list->head;
list->current->prev = nNode;
list->current->prev->next = list->current;
list->head = nNode;
}
}
void BubbleSort(List* list)
{
if (list->head == NULL)
{
printf("Lista jest pusta\n");
}
else if (list->head->next == NULL)
{
printf("Lista ma jeden element.\n");
}
else if (list->tail->prev == list->head)
{
if (list->head->data > list->tail->data)
{
list->current = list->tail;
list->current->next = list->current->prev;
list->current->prev = NULL;
list->current->next->prev = list->current;
list->head = list->current;
list->tail = list->current->next;
list->tail->next = NULL;
}
}
else
{
bool is_sorted = false;
Node* temp = list->head;
while (is_sorted != true)
{
is_sorted = true;
temp = list->head;
while (temp->next != NULL)
{
if (*((int*)temp->next->data) < *((int*)temp->data))
{
is_sorted = false;
if (temp == list->head)
{
temp->next->prev = NULL;
list->head = temp->next;
}
else
{
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
}
temp->prev = temp->next;
if (temp->next == list->tail)
{
temp->next = NULL;
list->tail = temp;
}
else
{
temp->next = temp->next->next;
temp->next->prev = temp;
}
temp->prev->next = temp;
temp = temp->prev;
}
temp = temp->next;
}
}
}
}
void FreeList(List* list)
{
if (list->head == NULL)
{
printf("Lista jest pusta\n");
return;
}
else
{
Node* temp = list->head;
while (temp != NULL)
{
Node* next = temp->next;
free(temp);
temp = next;
}
free(list->head);
free(list->tail);
free(list->current);
free(list);
}
}
void Show(List* list)
{
if (list->head == NULL)
{
printf("Lista jest pusta\n");
return;
}
else
{
printf("Wartosci: ");
list->current = list->head;
while (list->current != NULL)
{
printf("%d ", *((int*)list->current->data));
list->current = list->current->next;
}
printf("\n");
return;
}
}
Вот моя проблема! Мне нужно написать функцию, которая удаляет все из памяти. Я пробовал несколько вещей, но каждый раз, когда возникает ошибка. Я безнадежен, поэтому любая подсказка будет полезна. Вот код конкретной функции:
void FreeList(List* list)
{
if (list->head == NULL)
{
printf("Lista jest pusta\n");
return;
}
else
{
Node* temp = list->head;
while (temp != NULL)
{
Node* next = temp->next;
free(temp);
temp = next;
}
free(list->head);
free(list->tail);
free(list->current);
free(list);
}
}
Я надеюсь, что кто-то поможет :D
Связано это с тем, что большинство ваших алгоритмов сомнительны, помимо проблемы, обнаруженной Бармаром. Никогда не должно быть времени, когда начало или конец списка ненулевые, а другой — нулевой. Для пустого списка они оба должны быть нулевыми. Для списка с одним узлом и голова, и хвост должны ссылаться на один и тот же узел, а указатели next и prev этого узла должны быть нулевыми. И для всего остального head должен указывать на первый, prev этого узла должен быть нулевым, tail должен указывать на последний, эти узлы next должны быть нулевыми, а все указатели между ними должны быть правильно связаны в обоих направлениях.
Вам не нужны эти три вызова:
free(list->head);
free(list->tail);
free(list->current);
Эти узлы уже были освобождены, когда вы перебирали элементы списка. В частности, list->head
было первым значением temp
.
Один из способов выяснить, что происходит, — написать
main
, который создаст небольшой список, а затем вместоfree
использовать какой-нибудьmyFree
, который выводит адрес и затем вызываетfree
. Таким образом, вы увидите, когда какой-либо блок памяти будет освобожден во второй раз по ошибке.