2015-05-20 103 views
0

我想寫一個函數,可以添加新的結構到鏈表的末尾。而它總是出現分段錯誤。C:鏈接列表推段錯誤

void 
push(stk_t *stklist, info_t *gds) 
{ 
    stk_t *current = stklist; 

    if (current == NULL) 
    { 
     current->gds = (info_t *)malloc(sizeof(info_t)); 
     current->gds = gds; 
     current->next = (stk_t *)malloc(sizeof(stk_t)); 
     current->next = NULL; 
    } 
    else 
    { 
     while (current != NULL) 
     { 
      current = current->next; 
     } 
     current->next = (stk_t *)malloc(sizeof(stk_t)); 
     current->next->gds = (info_t *)malloc(sizeof(info_t)); 
     current->next->gds = gds; 
     current->next->next = (stk_t *)malloc(sizeof(stk_t)); 
     current->next->next = NULL; 
    } 

} 

我的結構

typedef struct{ 
    char name[NAME_SIZE]; 
    char aisle; 
    int shelf; 
    int weight; 
    int price; 
    int quantity; 
} info_t; 


typedef struct stk stk_t; 

struct stk{ 
    info_t *gds; 
    stk_t *next; 
}; 

功能推的目的()是第二個參數添加到鏈接列表的末尾。

+1

提示:當你做'電流 - > GDS =(info_t *)malloc(sizeof(info_t));','current'具有什麼值? – molbdnilo

+3

'if(current == NULL) { current-> gds' - 解引用NULL指針。 – szczurcio

+0

@molbdnilo糟糕,我打破了你的暗示。當我發佈時沒有看到它,對不起。 – szczurcio

回答

2

您的代碼push()是非常錯誤的。

gds分配,並立即覆蓋:

current->gds = (info_t *)malloc(sizeof(info_t)); 
    current->gds = gds; 

即使currentNULL,將立即取消引用(這是最有可能導致分段故障):

if (current == NULL) 
{ 
    current->gds = (info_t *)malloc(sizeof(info_t)); 

另外,不要明確地轉換結果malloc


如果我明白你想要做什麼,推應該看起來像這樣。

void 
push(stk_t **stklist, info_t *gds) 
{ 
    stk_t* current = *stklist; 

    // Create & initialize new entry 
    // gds is passed as parameter, so use it! 
    stk_t* newstk = malloc(sizeof(stk_t)); 
    newstk->gds = gds; 
    newstk->next = NULL; 

    // No entries had been inserted, overwrite root pointer 
    if(current == NULL) { 
     *stklist = newstk; 
     return; 
    } 

    // Find last entry that has available ->next 
    while(current->next != NULL) 
     current = current->next; 

    current->next = newstk; 
} 

... 

// Use it like this 
stk_t* root = NULL; 
push(&root, ...); 
push(&root, ...); 
push(&root, ...); 

這是非常地道 - 保持指針的第一入口,併爲第一個條目覆蓋指針本身,後者進入最後一個條目,它覆蓋next。順便說一句,這不是,但簡單單鏈表

對於堆棧實施,將是這樣的:

void 
push(stk_t **stklist, info_t *gds) 
{ 
    stk_t* newstk = malloc(sizeof(stk_t)); 
    newstk->gds = gds; 
    newstk->next = *stklist; 

    // Push new entry on top of the stack 
    *stklist = newstk; 
} 

info_t* 
pop(stk_t **stklist) { 
    stk_t* current = *stklist; 
    info_t* gds; 

    if(!current) 
     return NULL; 

    // Remove entry from top of the stack and 
    // use next entry as new top 
    *stklist = current->next; 
    gds = current->gds; 
    free(current); 

    return gds; 
} 
+0

thx很多,問題修復。 –