Попытка удалить элемент из двойного связанного списка в c

У меня возникла проблема при попытке удалить элемент из двусвязного списка в c.

Nodes_t *remove_Nodes (Nodes_t *a, Nodes_t b){
    Nodes_t *head;
    head=a;
    if ((a->i_pos==b.i_pos) && (a->j_pos==b.j_pos)){
        if (a->next=NULL){
            return NULL;
            }
        else {
            head=a->next;
            head->previous=NULL;
            return head;
            }
        }
    else if ((a->i_pos!=b.i_pos) || (a->j_pos!=b.j_pos)){
        while ((a->next->i_pos!=b.i_pos)||(a->next->j_pos!=b.j_pos)){
            a=a->next;
            if (a->next=NULL){
                return head;
                }
            }
        a=a->next;
        a->previous->next=a->next;
        if (a->next=NULL){
            return head;
            }
        else if (a->next!=NULL){
            a->next->previous=a->previous;
            return head;
            }               
        }
        return head;        
    }

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

В частности, как я проверил, функция работает нормально, пока не дойдет до этой точки.

else {
            head=a->next;
            head->previous=NULL;// HERE 
            return head;
            }

Структура, которую я использую, это

typedef struct Nodes {
char    position;
int     i_pos, j_pos;
int     g_distance;
int     h_distance;
int     F_estim;
struct Nodes    *parent;
struct Nodes    *next;
struct Nodes    *previous;

}Nodes_t;

person Hobowpen    schedule 07.04.2013    source источник
comment
Родитель, следующий, предыдущий, позиция, i_pos и j_pos? Что это за связанный список?!   -  person Kerrek SB    schedule 08.04.2013
comment
После трех проходов чтения я пришел к выводу, что код можно уменьшить менее чем вдвое от исходного размера. Меньше строк == меньше шансов на ошибку == меньше чтения. (в качестве побочного эффекта ошибка вылезет на поверхность. В большинстве случаев)   -  person wildplasser    schedule 08.04.2013
comment
Следующая, предыдущая работа для двусвязного списка. Другие переменные и указатели работают для реализации A_star, которую я пытаюсь сделать.   -  person Hobowpen    schedule 09.04.2013


Ответы (1)


Вы использовали присваивание = вместо сравнения == здесь:

if (a->next=NULL){

Что будет оцениваться как NULL, что неверно, поэтому перейдет к вашему предложению else, где вы делаете

head=a->next;
head->previous=NULL;

Таким образом, head становится NULL, затем вы пытаетесь разыменовать указатель NULL, чтобы получить его элемент previous.

  • Быстрое исправление: добавьте недостающее = в первую процитированную мной строку.
  • Лучшее решение: рефакторинг кода. Он слишком длинный и содержит ненужные биты. И не забудьте проверить операции равенства.
person lxop    schedule 07.04.2013
comment
Хороший улов! Я упустил из виду (вызванный поиском структуры программы...) - person wildplasser; 08.04.2013
comment
Спасибо, чувак, я не могу поверить, что пропустил это. Я также попытаюсь реорганизовать свой код. - person Hobowpen; 08.04.2013