2013-05-16 29 views
-1

我想實現一個雙向鏈表,其行爲像一個隊列(我希望它像隊列一樣)。雙鏈表 - 分段錯誤 - C

[編輯]

當我將節點添加到列表(例如5個節點)和清空列表(刪除所有元素),並嘗試添加一個節點再次列表,它給了我一個分段錯誤(核心轉儲)錯誤。

linkedlist.h 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 


typedef struct node{ 
    int d; 
    struct node *prev; 
    struct node *next; 
}node; 

typedef struct linkedlist{ 
    int size; 
    struct node *first; 
    struct node *last; 
}linkedlist; 




linkedlist.c 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#include "linkedlist.h" 

linkedlist* createList(){ 
    linkedlist* myList = (linkedlist*)calloc(1,sizeof(linkedlist)); 
    myList->first = NULL; 
    myList->last = NULL; 
    myList->size =0; 

    return myList; 

} 

static node* createNode(int n){ 
    node *myNode = (node*)calloc(1,sizeof(node)); 

    myNode->d = n; 

    myNode->prev = NULL; 
    myNode->next = NULL; 

    return myNode; 
} 

void insertNode(linkedlist* l, int num){ 
    node *temp, *newNode; 

    newNode = createNode(num); 

    if (l->size == 0){ 
     newNode->next = NULL; 
     newNode->prev = NULL; 

     l->first = newNode; 
     l->last = newNode; 

     l->size++; 

    } 

    else{ 
     temp = l->first; 
     while (temp->next != NULL){ 
      temp = temp->next; 
     } 

     newNode->prev = temp; 
     temp->next = newNode; 
     newNode->next = NULL; 

     l->size++; 

    } 


} 

int deleteNode(linkedlist* l){ 
    node *temp = calloc(1,sizeof(node)); 

    if (l->first ==NULL){ 
     return -1; 
    } 

    else if (l->size ==1){ 

     free(l->first); 
     l->first= NULL; 
     l->last = NULL; 


     l->size--; 

    } 

    else if (l->size > 1){ 
     temp = l->first; 
     l->first = temp->next;   

     free(temp); 
    } 


} 

void display(linkedlist *l){ 
    node *temp = calloc(1,sizeof(node)); 
    temp = l->first; 

    if (temp == NULL){ 
     printf("The list is empty\n"); 
    } 
    while (temp != NULL) { 
     printf("-> %d ", temp->d); 
     temp = temp->next; 
    } 
} 
int main(){ 

    linkedlist *myList = createList(); 

    int choice, temp=0, numb; 
    printf("(1) Insert \n (2) Delete \n"); 

    for (temp; temp<10; temp++){ 
    printf("Choice :"); 
    scanf ("%d", &choice); 
    switch(choice) { 
     case 1: { 
      printf("Enter a Number: "); 
      scanf("%d", &numb); 
      insertNode(myList, numb); 
      display(myList); 
      break; 
     } 
     case 2:{ 
      deleteNode(myList); 
      display(myList); 
      break; 

     } 
    } 

    }  
} 
+0

'的malloc()'阿婷內存在'刪除()'函數是不是有悖常理以上(,然後陪同一個不錯的小內存泄漏)。投射malloc()的返回值是一個錯誤,所以在分配內存時使用'sizeof(TYPE)'而不是'sizeof(* pointer)'。文體方面的注意事項:除非採用'foo_bar'(或POSIX中的'foo_bar_t')的形式,小寫的typenames在可讀性方面是一個壞主意。 – 2013-05-16 07:24:23

+0

不確定當你已經有最後一個ptr時,爲什麼你循環到列表的末尾?也使用calloc而不是malloc來將所有事件初始化爲0,最後不要強制使用malloc/calloc的返回值 –

回答

1

在你離開的第一指向釋放的內存,如果大小爲1

的deleteNode它應該是:

else if (l->size ==1){ 
    free(l->first); 
    l->first = NULL; 
    l->last = NULL; 
    l->size--; 
} 

而且溫度是你不需要分配內存的指針與它malloc

2

在您的刪除節點功能:

else if (l->size > 1){ 
     temp = l->first; 
     l->first = NULL;  //this is problem 
     l->first->next = NULL; 
     temp->next = l->first; 

     l->first->prev = NULL; 

您正在分配l->first = NULL,然後在下一個語句l->first->next = NULL;中訪問它,這將失敗並給您分段錯誤。

此外,當l->size == 1你還應該釋放它後設置l->first = NULL

1

訪問「NULL」位置時出現問題。讓我們修改代碼:

temp = l->first; 
l->first = NULL;  // here, you set l->first = 0 
l->first->next = NULL; // here, you access to 0->next: this is not correct. 
temp->next = l->first; 

其更改爲:

temp = l->first; 
l->first = temp->next; 
delete temp; 
1
int deleteNode(linkedlist* l){ 
    node *temp= (node*)malloc(sizeof(node)) ; 

    if (l->first ==NULL){ 
     return -1; 
    } 

    else 
{ 
temp= l->first; 
l->first= temp->next; 
l->first->previous= temp; 
l->size--; 
free(l->first->previous); 
} 
}