typedef struct l_node {
line* data;
struct l_node* next;
struct l_node* prev;
} l_node;
typedef struct {
l_node* first;
l_node* last;
} list;
void Lcreate(list **lst) {
(*lst) = (list *)malloc(sizeof(list));
(*lst)->first = (*lst)->last = (l_node *)malloc(sizeof(l_node));
(*lst)->first->next = (*lst)->last;
(*lst)->last->prev = (*lst)->first;
(*lst)->first->prev = NULL;
(*lst)->last->next = NULL;
}
Теперь посмотрим на функцию добавления элемента в список. Здесь потенциальные проблемы могут быть в использовании указателей. void Ladd(list *lst, line *ln) {
l_node *t = (l_node *)malloc(sizeof(l_node));
if (!t) {
// Обработка ошибки malloc
fprintf(stderr, "Memory allocation failed\n");
return;
}
t->data = ln;
t->next = lst->last;
t->prev = lst->last->prev;
if (lst->last->prev != NULL) {
lst->last->prev->next = t;
}
lst->last->prev = t;
if (lst->first == lst->last) {
// Это значит, что список был пустой до добавления элемента
lst->first = t;
}
}
Обратите внимание, что при добавлении первого элемента в список через функцию Lcreate, структура инициализируется так, что lst->first и lst->last указывают на один и тот же узел. Это означает, что для корректной работы кода добавления элементов, нам нужно правильно обрабатывать первый элемент и не забывать обновлять указатели first и last. if (lst->first == lst->last) {
lst->first = t;
}
Таким образом, функция добавления элемента будет правильно работать как для пустого, так и для непустого списка. bool Ladd(list *lst, line* ln) {
l_node *t = (l_node *)malloc(sizeof(l_node));
if (!t)
return false;
t->data = ln;
t->next = lst->last;
if (Lempty(lst)) {
t->prev = NULL;
lst->first = t;
} else {
t->prev = lst->last->prev;
lst->last->prev->next = t;
}
return true;
}
bool Ladd(list *lst, line* ln) {
l_node *t = (l_node *)malloc(sizeof(l_node));
if (!t)
return false;
t->data = ln;
t->next = lst->last;
if (Lempty(lst)) {
t->prev = NULL;
lst->first = t;
} else {
t->prev = lst->last->prev;
lst->last->prev->next = t;
}
lst->last->prev = t; // Эта строка добавлена
return true;
}
bool Lempty(list *lst) {
return (lst->first == lst->last);
}
попробуй так
#include
#include
// Структура узла списка
typedef struct l_node {
void* data;
struct l_node* next;
struct l_node* prev;
} l_node;
// Структура списка
typedef struct {
l_node* first;
l_node* last;
} list;
// Инициализация списка
void Lcreate(list **lst) {
*lst = (list *)malloc(sizeof(list));
(*lst)->first = NULL;
(*lst)->last = NULL;
}
// Добавление элемента в конец списка
void Ladd(list *lst, void *data) {
l_node *new_node = (l_node *)malloc(sizeof(l_node));
new_node->data = data;
new_node->next = NULL;
new_node->prev = NULL;
if (lst->first == NULL) {
// Список пустой
lst->first = new_node;
lst->last = new_node;
} else {
// Список не пустой
new_node->prev = lst->last;
lst->last->next = new_node;
lst->last = new_node;
}
}
// Удаление узла из списка
void Lremove(list *lst, l_node *node) {
if (lst->first == NULL || node == NULL) return;
if (node == lst->first) {
lst->first = node->next;
if (lst->first != NULL) {
lst->first->prev = NULL;
} else {
lst->last = NULL;
}
} else if (node == lst->last) {
lst->last = node->prev;
if (lst->last != NULL) {
lst->last->next = NULL;
} else {
lst->first = NULL;
}
} else {
node->prev->next = node->next;
node->next->prev = node->prev;
}
free(node);
}
// Освобождение памяти списка
void Ldestroy(list *lst) {
l_node *current = lst->first;
l_node *next_node;
while (current != NULL) {
next_node = current->next;
free(current);
current = next_node;
}
free(lst);
}
int main() {
list *myList;
Lcreate(&myList);
int data1 = 1, data2 = 2, data3 = 3;
Ladd(myList, &data1);
Ladd(myList, &data2);
Ladd(myList, &data3);
// Удаление среднего узла (data2)
Lremove(myList, myList->first->next);
// Освобождение памяти списка
Ldestroy(myList);
return 0;
}
У меня есть узел списка И сам список список: Инициализируется список таким образом: Я хочу добавить новый элемент в список. Для этого я сначала выделяю под него память: Затем записываю необходимые данные в новый элемент: Затем присваиваю предпоследнему элементу указатель на новый элемент: Однако на этом шаге программа прекращает свою работу, не выводя никаких ошибок. Также стоит учитывать, что на данном этапе в списке уже есть один элемент, ведь добавление элемента в пустой список обрабатывается отдельно: В чём проблема? Почему это не работает?