2013-07-09 2 views
0

Я изучаю, как строить связанные списки в C. Моя программа компилируется, но по какой-то причине я не могу понять, я получаю ошибку сегментации . Я пытался выяснить проблему на некоторое время, но мне не повезло. Вот дефектный код:Ошибка сегментации - Связанный список

int len() 
{ 
    struct list * current = head; 
    int length = 0; 

    while (current != NULL) 
    { 
     length++; 
     current = current -> next; //move to next node 
    } 
    return length; 
} 


struct list * search (int key) 
{ 
    struct list * current = head; 

    while (current != NULL && current->data != key) 
     current = current -> next; 

    if (current != NULL && current -> data == key) 
     return current; 
    return NULL; 
} 



/* Insert a new data element with key d into the end of the list. */ 
void insert(int d) // at the end 
{ 
    struct list * current = head; 
    struct list * new; 
    while (current -> next != NULL) 
     current = current -> next; 
    new = (struct list *)malloc(sizeof(struct list)); 
    new -> data = d; 
    current -> next = new; 
    new -> next = NULL;  
} 


void insertAfter(int d, int where) // insert at the middle 
{ 
    struct list * marker = head; 
    struct list * new; 

    while(marker -> data != where) 
     marker = marker -> next; 
    new = (struct list*)malloc(sizeof(struct list)); 

    new -> next = marker -> next; 
    marker -> next = new; 
    new -> data = d; 
} 


/* Remove the node with value d from the list */ 
/* assume no duplicated keys in the list */ 
/* If the list is empty, call prtError() to display an error message and return -1. */ 

void delete(int d) 
{ 
    struct list * current1 = head; 
    struct list * current2; 

    if (len() == 0) 
    { //prtError("empty"); 
     exit(0); 
    } 
    if (head -> data == d) 
    { 
     head = head -> next; 
    } 

    //Check if last node contains element 
    while (current1->next->next != NULL) 
     current1 = current1->next; 

    if(current1->next->data == d) 
      current1->next == NULL; 


    current1 = head; //move current1 back to front */ 

    while(current1 -> next -> data != d) 
     current1 = current1 -> next; 

    current2 = current1 -> next; 
    current1 -> next = current2 -> next; 

} 

Я получаю ошибку в сегментации в методе удаления на линии:

while(current1 -> next -> data != d) 

Почему это так?

+0

В какой функции вы получаете ошибку сегментации? – Jashaszun

+2

Если вы запустите его в отладчике, где отладчик говорит, что происходит ошибка сегментации? – Simon

+1

Я не думаю, что 'новый' зарезервирован в C, но вы, вероятно, не должны использовать его как имя переменной. Ваша функция 'delete' выглядит как вероятный кандидат, у вас есть' if (head -> data == d) 'w/o check для' NULL' и 'current1-> next-> next', вероятно, тоже не хорошо, и' insert' имеет 'current -> next' w/oa' NULL' чек. –

ответ

0

Есть много проблем с кодом, который вы публикуете, но ваше упоминание в ваших комментариях вас касается insert(). Причина, по которой он выходит из строя, заключается в том, что вы будете разыскивать указатель NULL, если head имеет значение NULL, когда вызывается insert().

Вам потребуется специальный случай для вставки в head когда NULL:

if (head) { 
    while (current -> next != NULL) 
     current = current -> next; 
} 
new = (struct list *)malloc(sizeof(struct list)); 
new -> data = d; 
if (current) { 
    current -> next = new; 
} else { 
    head = new; 
} 
new -> next = NULL; 

Вы должны проверить аналогичные вопросы в своих других функций. Используйте функцию search() в качестве примера предотвращения разыменования указателя NULL в вашем цикле.

0

У вас есть несколько вопросов, в insert:

while (current -> next != NULL) 

вы не проверяя, если current является NULL. Есть аналогичные вопросы в delete:

if (head -> data == d) 

вам нужно проверить head здесь и:

while (current1->next->next != NULL) 

также является проблемой.

+0

Возникает другая проблема: «current -> next = new;» в методе вставки. Что не так с этой линией? Это моя первая попытка Связанных списков в C Я все еще участвую! – Sophie

+0

@Sophie Эта строка 'while (current-> next! = NULL) current = current-> next;' будет гарантировать, что 'current' является' NULL' –

+0

. Я получаю ошибку сегментации в методе удаления в строке: while (current1 -> next -> data! = d) – Sophie

0

Ошибка вставки после того, как вы закроете конец списка, элемент не найден.

0

В insert,

while(current->next != NULL) current = current->next; 

Это будет гарантировать, что current == NULL.

current->next = new; 

Сбой его каждый раз.

0

Может быть, это в insertAfter:

while(marker -> data != where) 
    marker = marker -> next; 

Если ни один узел с data == where не найден, будет NULL указатель.
NULL указатель разыменовывается в коде:

new = marker -> next; 

Это делает Segfault.Проверяется marker->next != NULL следует избегать, что:

while(marker->next != NULL && marker -> data != where) 
    marker = marker -> next; 

Но вы должны попытаться скомпилировать программу с символами отладки (-g опция) и запустить его строка за строкой в ​​отладчик, как GDB.

Смежные вопросы