2011-08-11 29 views
1

我有一個通用的雙向鏈表實現,並且正在處理插入。插入之後,我嘗試從腳開始向後遍歷列表,並且出現總線錯誤。爲了測試代碼,並嘗試隔離錯誤,我已經在(不是最好的調試程序,但有用於一目瞭然地告訴我我的代碼正在做什麼)散佈打印語句。要嘗試查看問題出現的位置,在每次插入後,我要求列表中倒數第二個元素的值。我總是以5,2,10,80,4,1,7,8的順序插入元素,並且在將4插入到列表中後,它始終扼流。程序的完整代碼如下。排序的雙向鏈表給出了反向訪問時的總線錯誤

dlist_t * 
insert_in_order (dlist_t *list, void *value, size_t size, 
    int (*cmp_fptr)(const void *, const void *)) 
{ 
dlnode_t * prev = NULL; 
dlnode_t * current = list->head; 
dlnode_t * newnode = safe_malloc(sizeof(dlnode_t)); 

newnode->data = value; 
newnode->next = NULL; 
newnode->prev = NULL; 

printf("Beginning list loop for %d.\n", *(int *) newnode->data); 
while (current != NULL && cmp_fptr(newnode->data, current->data) != -1) 
{ 
    prev = current; 
    current = current->next; 
} 
printf("Insertion point found.\n"); 

newnode->next = current; 
newnode->prev = prev; 

if (prev == NULL) 
{ 
    printf("Setting for new head\n"); 
    list->head = newnode; 
} 
else 
{ 
    printf("Setting previous next to new node\n"); 
    prev->next = newnode; 
} 

if (current == NULL) 
{ 
    printf("setting for new foot."); 
    list->foot = newnode; 
} 
else 
{ 
    printf("Setting for new current previous\n"); 
    current->prev = newnode; 
} 

list->list_len++; 
list->size = sizeof(list); 
printf("Insertion compete for %d\n\n", *(int *) newnode->data); 
printf("Data for surrounding:\n"); 
if(newnode->next !=NULL) 
{ 
    printf("Next is %d \n", *(int *) newnode->next->data); 
} 
if(newnode->prev != NULL) 
{ 
    printf("Prev is %d \n\n", *(int *) newnode->prev->data); 
} 

if(list->foot->prev != NULL) 
{ 
    printf("Gonna print secondlast!\n"); 
    printf("secondlast is%d \n\n", *(int *)list->foot->prev->data); 
} 

return list; 
} 

列表定義是非常基本的,只是

struct dlnode 
{ 
    void *data;  /* A pointer to a generic satellite data payload */ 
    dlnode_t *next; /* A pointer to the next item in the list */ 
    dlnode_t *prev; /* A pointer to the previous item in the list */ 
}; 

typedef struct 
{ 
    dlnode_t *head; /* A pointer to the head node of the list */ 
    dlnode_t *foot; /* A pointer to the foot node of the list */ 
    int list_len; /* Total number of items in the list */ 
    int size;  /* Size of the list in bytes */ 
} dlist_t; 

你可以改變但是你想要的功能定義,是的safe_malloc只是malloc的快捷方法,如果您正在測試一個可以取代代碼你自己。 cmp_fptr是一個函數指針,指向一個簡單的'是比b'更大的方法。

編輯:UPDATE 線

printf("secondlast is%d \n\n", *(int *)list->foot->prev->data); 

是什麼原因導致程序中止,我用了一個調試器。將項目插入列表時,會在多行插入後暫停該行。 以下是我現在使用的測試用例代碼。

int * 
alloc_data (int val) 
{ 
    int *rv = safe_malloc (sizeof (int)); 
    *rv = val; 
    return (rv); 
} 

int 
main (void) 
{ 
    dlist_t *list = NULL; 
    int *num = NULL, *rv = NULL; 
    dlnode_t *tnode = NULL; 

    list = make_empty_list(); 

    list = insert_in_order (list, alloc_data (5), sizeof(int), cmp_int); 
    list = insert_in_order (list, alloc_data (2), sizeof(int), cmp_int); 
    list = insert_in_order (list, alloc_data (10), sizeof(int), cmp_int); 
    list = insert_in_order (list, alloc_data (80), sizeof(int), cmp_int); 
    list = insert_in_order (list, alloc_data (4), sizeof(int), cmp_int); 
    list = insert_in_order (list, alloc_data (1), sizeof(int), cmp_int); 
    list = insert_in_order (list, alloc_data (7), sizeof(int), cmp_int); 
    list = insert_in_order (list, alloc_data (8), sizeof(int), cmp_int); 
    return(EXIT_SUCCESS); 
} 

還有一點點它,但這就是我現在測試的一切。

感謝您的名單 - >大小提示,我不太清楚我最初的想法。

edit2:感謝safe_malloc errorfinding,我認爲這是問題的原因,但我仍然得到相同的錯誤。在插入4之後,調試器給了我一個sigsegv(分段錯誤),並且它到達了我要求list-> foot-> prev-> data(參見上面)的理由。

最終編輯:通過適當地爲節點數據分配足夠的空間來解決問題。感謝那些幫助。我的代碼中還存在其他問題,但最適合於另一個問題,以及關於不同的代碼片段。

+2

爲什麼不在調試器中運行這個?這會告訴你哪一行導致錯誤,然後你將能夠調查變量的值等。 –

+0

除了'list-> size = sizeof(list);'外,你的代碼看起來相當健全,我敢說你敢說服我是對的。 (當[list-> foot-> prev!= NULL)''當list-> foot == NULL'時也是不好的)。像@Oli說的那樣通過調試器來運行它,並且/或者發佈更多的代碼。 – user786653

回答

1

有幾件事情:

因爲它已經說過,list->size = sizeof(list);可能不會做你認爲

作爲參數傳遞的size_t size可能是你的主要問題,似乎危險(這是什麼變量當你調用函數與錯誤的大小做dlnode_t * newnode = safe_malloc(size);值?)

可以解釋您的問題

dlnode_t * newnode = safe_malloc(size);

也許應該由

dlnode_t * newnode = safe_malloc(sizeof(dlnode_t));

末被替換,在列表中,你使用它直接void *value,而不是一個副本。 所以,如果你不是總是在同一個塊中調用這個函數,你將會遇到問題

具有相同的函數簽名,我認爲size參數應該代表value參數的大小,以使malloc/memset爲它並將其保存在您的列表中

+0

感謝您的建議。我修改了我的代碼併發布了更多內容供大家查看,而且我仍然遇到錯誤。我承認我不知道我應該如何處理list-> size並更新它。 – buggritall