C - Удаление любого узла из двусвязного списка - PullRequest
0 голосов
/ 21 мая 2018

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

Я создаю свой список с заголовком, например:

typedef struct Inode2*Task;                                     
typedef struct Inode2{
        int ID;
        int Priority;
        int Status;
        char *Description;
        Person *person;
        Date   *creation;
        Date   *deadline;
        Date   *conclusion;                             
        Task next;
        Task previous;
    }Task_node2;    

Task TaskCreate()                                                                                                           {
    Task aux=(Task)malloc(sizeof(Task));
    aux->next=NULL;
    aux->previous=NULL;
    return aux;
}

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

У меня есть функция для вставки узла в конец этого списка.,Кажется, это работает отлично.

Всякий раз, когда я использую эту функцию удаления для первого элемента, она падает:

int TaskRemove(Task h,int IDREMOVE)                                                                                         {
    int val;
    for(;h;h=h->next)
    {
        if (h->ID==IDREMOVE)
        {
            h->previous->next = h->next;
            val++;
            if (h->previous->previous==NULL)
            {
                h->previous->next = h->next;
            }
        }
    }
    if (val==0)
    {
        printf("\n\tNo node with such ID\n");
        sleep(1);
    }
    return val;
}

Это работает на каждом элементе, кроме последнего.Что происходит?Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Первая проблема с вашим кодом - как вы распределяете память для узла.

Task aux=(Task)malloc(sizeof(Task));

Эта строка выделяет sizeof(Task) байтов памяти.Task это указатель, а не фактический узел.В зависимости от компилятора, он, скорее всего, выделит достаточно места для указателя.Для выделения места для Inode2 следует использовать следующее:

Task aux=(Task)malloc(sizeof(struct Inode2));

Вторая проблема заключается в этих строках:

h->previous->next = h->next;
val++;
if (h->previous->previous==NULL)
{
    h->previous->next = h->next;
}

Для первого элемента h->previous должно быть NULL, поэтому при попытке доступа к h->previous->next программа пытается получить доступ к указателю NULL, что вызывает сбой.Вы должны проверить, является ли h->previous NULL или нет, прежде чем пытаться получить доступ дальше.

Примечания:

  • Как указано в комментарии, выполните НЕ указатели на typedef.
  • Вы сказали, что он падает на первом элементе, затем сказали, что он работает на каждом элементе, кроме last .Я предполагаю, что первое.
0 голосов
/ 21 мая 2018

Проблема в том, что ваш код обращается к узлу с двумя узлами без проверки, существует ли соответствующий узел с одним узлом.Удаление последнего узла в списке приведет к аналогичной проблеме.

Вам необходимо NULL -проверить каждый указатель перед применением к нему оператора ->.В частности, код, который проверяет h->previous->previous == NULL, должен сначала убедиться, что h->previous не является NULL.Вам необходимо добавить NULL проверку первого указателя во всех местах, где вы выполняете двойную проверку или присваивание.

Примечание: В вашем коде есть другие проблемы, например, malloc(sizeof(Task)) возвращает память неправильного размера.Основной случай путаницы заключается в том, что Task является типом указателя, но он используется без звездочки.Вам следует избегать этой ситуации, если это возможно, используя Inode2* напрямую или переименовывая Inode2 в Task для лучшей читаемости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...