2013-03-19 41 views
0

我試過在GDB中調試這個程序,但是我得到了一個非常奇怪的崩潰錯誤(SIGABRT)。它發生在我的流行功能,但我不知道爲什麼。有人能幫我嗎?非常感謝!GDB中一個奇怪的崩潰錯誤

我跨過GDB,我相信當i = 9時,崩潰發生,並在彈出功能中釋放(tmp)。

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

#define SIZE 10 
#define FALSE 0 
#define TRUE 1 


struct linkedStruct 
{ 
    int elem; 
    struct linkedStruct* next; 
}; 

typedef struct linkedStruct linked; 
typedef linked* linkedPtr; 

void push (linkedPtr* hd, int val) 
{ 
    linkedPtr ptr = (linkedPtr) malloc (sizeof(linked)); 
    ptr->elem = val; 
    ptr->next = *hd; 
    *hd = ptr; 
} 

int isEmpty (linkedPtr hd) 
{ 
    if (hd == NULL) 
     return TRUE; 
    else 
     return FALSE; 
} 


int top (linkedPtr hd) 
{ 
    return (hd->elem); 
} 

void pop (linkedPtr hd) 
{ 
    linkedPtr tmp = hd; 
    hd = hd->next; 
    free (tmp); 
} 

void show (linkedPtr hd) 
{ 
    while (hd != NULL) 
    { 
     printf ("%d, ", hd->elem); 
     hd = hd->next; 
    } 
    printf ("\n"); 
} 

int main (int argc, char**argv) 
{ 
    linkedPtr head = NULL; 
    int i; 
    int temp; 

    /* push 10 random values onto the stack showing the stack growing */ 
    for (i = 0 ; i < SIZE; ++i) 
    { 
     temp = rand() % 100; 
     printf ("In main(): temp: %6d\n", temp); 
     push (&head, temp); 
     show (head); 
    } 

    printf ("\n"); 

    /* remove the value from the stack */ 
    while (!isEmpty(head)) 
    { 
     printf ("Top of stack value is: %d\n", top(head)); 
     pop (head); 
    } 
} 
+0

提示:發生了什麼,當只有一個元素? – 2013-03-19 14:00:07

+1

你知道'hd'(比如'hd = hd-> next;')的任何變化在'pop()'完成後都不會保留,對吧? – m0skit0 2013-03-19 14:01:33

回答

0

這裏的實際問題是,改變hd不給調用者,從而導致free()被稱爲上已經被釋放的內存可見的,所以它產生未定義行爲

pop()應該是這樣的:

void pop (linkedPtr* hd) 
{ 
    linkedPtr tmp = *hd; 
    *hd = (*hd)->next; 
    free (tmp); 
} 

,並呼籲像這樣:

pop(&head); 
+2

'pop()'不會因爲按值傳遞而改變'hd'。 – m0skit0 2013-03-19 14:03:50

+0

@ m0skit0:是的,我也注意到了,只是有點晚了。因爲這是將'NULL'傳遞給調用者的一種方式,所以在這裏需要爲傳入的指針指定'next'。 – LihO 2013-03-19 14:12:21

+0

修復它非常感謝! – juice 2013-03-19 14:29:51