2015-12-15 3 views
1

Это мой текущий код, с которым я столкнулся, так что неправильное обращение к первому элементу или только к объекту - это первые 2 части этой функции. По какой-то причине я получаю ошибки памяти, если я просто пытаюсь установить node = node-> next_ .. Я бы предположил, что это будет самый простой способ, но когда я брошу это обратно в программу, я начну получать проблемы с доступом к памяти. все остальные части работают нормально, пока я не манипулирую адресом головы.Удаление узла из дважды связанного списка

void removeNode(struct student_record_node* node) 
{ 
    struct student_record_node *temp=NULL; 
    temp=node; 
    if(node->next_==NULL&&node->prev_==NULL) 
    { 
     node=node->next_ 
     free(node->prev_); 
    } 
    else if(node->prev_==NULL&& node->next_!=NULL) 
    { 
     node=node->next_ 
     free(node->prev_); 
    } 

    else if(node->next_!=NULL && node->prev_!=NULL) 
    { 
     node->prev_->next_ = node->next_; 
     node->next_->prev_ = node->prev_; 
     student_record_node_deallocate(node); 
    } 
    else if(node->prev_!=NULL&& node->next_==NULL) 
    { 
     node->prev_->next_=node->next_; 
     student_record_node_deallocate(node); 
    } 
} 
+1

Пожалуйста, пост [Minimal полный и проверяемый Пример] (https://stackoverflow.com/help/ mcve). Основная причина может быть или не быть в этом коде или только в этом коде. – kaylum

+0

В двусвязном списке никогда не должно быть указателя нулевого узла для следующего или предыдущего. Если есть только один узел, он указывает на себя. 'node-> next-> prev = node-> prev; node-> prev-> next = node-> next; free (node); ' – WalterM

+1

@WalterM Нет необходимости, чтобы двусвязный список не содержал нулевого указателя. В двусвязном списке prev головного узла NULL, а следующий из последнего узла - NULL. То, что вы говорите, присутствует в круговом списке ссылок. – Nutan

ответ

1

Есть несколько ошибок:

  1. Узел может быть голова, так struct student_record_node* должны быть возвращены, а не void.

  2. узел может быть NULL

  3. если node->prev_ является NULL, убедитесь, чтобы освободить узел удален.

+1

' free' с параметром 'NULL' не вызовет серьезных проблем. На странице [free man] (http://linux.die.net/man/3/free): «Если ptr имеет значение NULL, операция не выполняется». – kaylum

+0

мой ошибка. Я отредактирую ответ – seamaner

1

Поскольку вы не предоставили, что ваш связанный список выглядит, я буду считать для моего кода-например, что это структура, содержащая указатель на head связанный список (первый элемент). Относится к your_list.

Проблема заключается в первых двух if -блоках в вашем коде;

  • Первый if: if(!node->next_ && !node->prev_):

    Это означает, что вы удаляете головной элемент списка. В этом случае вам нужно будет явно настроить голову на NULL вместо того, чтобы указывать указатель на узел, который вы хотите удалить, на NULL (путем установки его предшественнику, который равен NULL). Кроме того, вы освобождаете NULL -Pointer, освобождая предыдущий узел. Это само по себе не проблема, но вы хотите удалить node, а не его предшественника.

  • Второй if: if(!node->prev_ && node->next_):

    Это означает, что вы удаляете голову, но список не будет пустым после того, как узел будет удален. В этом случае вы должны установить головку списка, чтобы указать на новую голову, которая будет узлом, на который указывает node->next_. Кроме того, у вас есть аналогичная проблема с free(), как и раньше.

Решение этих двух точек, ваш код должен сделать что-то вдоль линий этого:

void removeNode(struct student_record_node *node){ 
    if(!node->next_ && !node->prev_){ 
     your_list->head = NULL; // Remove head - List is now empty. 
     student_record_node_deallocate(node); 
     node = NULL; // Set freed pointer to NULL, for safety. 
    } 
    else if(!node->prev_ && node->next_){ 
     your_list->head = node->next_; // Set the head to the new head. 
     student_record_node_deallocate(node); 
     node = NULL; // Set freed pointer to NULL, for safety. 
    } 
    else if(node->next_ && node->prev_){ 
     node->prev_->next_ = node->next_; 
     node->next_->prev_ = node->prev_; 
     student_record_node_deallocate(node); 
     node = NULL; // Set freed pointer to NULL, for safety. 
    } 
    else if(node->prev_ && !node->next_){ 
     node->prev_->next_ = NULL; 
     student_record_node_dealocate(node); 
     node = NULL; // Set freed pointer to NULL, for safety. 
    } 
} 
Смежные вопросы