Удаление первого узла связанного списка

-6

Я должен напечатать список набора в c, используя связанные списки (следовательно, указатели). Однако, когда я удаляю первый элемент списка и пытаюсь распечатать список, он просто отображает много адресов друг под другом. Какие-либо предложения о том, что может быть проблемой? Благодарю!

Функция удаления:

 int delete(set_element* src, int elem){
if (src==NULL) {
fputs("The list is empty.\n", stderr);
}

set_element* currElement;
set_element* prevElement=NULL;

for (currElement=src; currElement!=NULL; prevElement=currElement, currElement=currElement->next) {
if(currElement->value==elem) {
if(prevElement==NULL){
printf("Head is deleted\n");
if(currElement->next!=NULL){
*src = *currElement->next;
} else {

destroy(currElement);
}
} else {
prevElement->next = currElement->next;
}
// free(currElement);
break;
}
}

return 1;
}

void print(set_element* start)
{
set_element *pt = start;

while(pt != NULL)
{
printf("%d, ",pt->value);
pt = pt->next;
}
}

спросил(а) 2013-10-21T13:31:00+04:00 7 лет, 6 месяцев назад
0
62

Если указатель списка совпадает с указателем на первый элемент, указатель списка больше не действует, когда вы free первый элемент.

Существует два решения этой проблемы:

Пусть все ваши методы списка берут указатель на список, чтобы они могли обновлять его, когда это необходимо. Проблема с этим подходом заключается в том, что если у вас есть копия указателя в другой переменной, этот указатель также становится недействительным.

Не позволяйте указателю списка указывать на первый элемент. Пусть он указывает на указатель на первый элемент.

Образец кода:'

typedef struct node_struct {
node_struct *next;
void *data;
} Node;

typedef struct {
Node *first;
} List;

ответил(а) 2013-10-21T13:39:00+04:00 7 лет, 6 месяцев назад
44

Обычно это происходит, когда вы удаляете указатель (фактически часть памяти), который не принадлежит вам. Дважды проверьте свою функцию, чтобы убедиться, что вы не освобождаете тот же самый указатель, который вы уже освободили, или освободив указатель, который вы не создали с помощью "malloc".

ответил(а) 2013-10-21T13:38:00+04:00 7 лет, 6 месяцев назад
46

Предупреждение: этот ответ содержит выводимый код.

Типичный связанный список в C выглядит примерно так:

typedef struct _list List;
typedef struct _list_node ListNode;

struct _list {
ListNode *head;
}

struct _list_node {
void *payload;
ListNode *next;
}

Чтобы правильно удалить первый элемент из списка, необходимо выполнить следующую последовательность:

List *aList; // contains a list

if (aList->head)
ListNode *newHead = aList->head->next;

delete_payload(aList->head->payload); // Depending on what the payload actually is
free(aList->head);
aList->head = newHead;

Порядок операций здесь значителен! Попытка переместить голову без предварительного освобождения старого значения приведет к утечке памяти; и освобождение старой головы без предварительного получения правильного значения для новой головы создает неопределенное поведение.

Добавление: Иногда часть _list приведенного выше кода будет полностью опущена, оставляя списки и узлы списка как одно и то же; но из симптомов, которые вы описываете, я предполагаю, что это, вероятно, не так.

Однако в такой ситуации шаги остаются, по сути, одинаковыми, но без aList->.

Редактировать:

Теперь, когда я вижу ваш код, я могу дать вам более полный ответ.

Одна из ключевых проблем вашего кода заключается в том, что он повсюду. Есть, однако, одна строка здесь, особенно плохая:

*src = *currElement->next;

Это не работает, и это то, что вызывает ваш крах.

В вашем случае решение - либо связать связанный список каким-то образом с контейнером, как конструктор struct _list выше; или переработать существующий код, чтобы принять указатель на указатель на элемент set, чтобы вы могли передавать указатели, чтобы установить элементы (которые вы хотите сделать) назад.

Что касается производительности, эти два решения, вероятно, близки друг к другу, так как не имеют никаких шансов, но использование структуры списка упаковки помогает сообщать о намерениях. Это также помогает предотвратить перетаскивание других указателей в список из-за удаления головы, так что это.

ответил(а) 2013-10-21T13:37:00+04:00 7 лет, 6 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема