2015-10-10 30 views
1

該程序包含鏈接列表的典型節點結構(所以指向下一個節點的指針和包含值的int)。我有以下測試功能:傳遞給函數時分配空指針

void F(NODE** Y, int value) 
{ 
    NODE* X = *Y; 

    if(!X) 
    { 
     printf("case1...\n"); 
     X = (NODE*)malloc(sizeof(NODE)); 
     X->Data = value; 
     return; 
    } 
    printf("case2...\n"); 
    X->Next = (NODE*)malloc(sizeof(NODE)); 
    X->Next->Data = value; 
    return; 
} 

void myPrint(NODE** Y) 
{ 
    NODE* X = *Y; 
    printf("printing...\n"); 

    printf("%d %d\n", X->Data, X->Next->Data); 
    return; 
} 

int main() 
{ 
    NODE* n = NULL; 

    F(&n, 5); 
    F(&n, 10); 

    myPrint(&n); 
} 

這段代碼產生在Linux下面的輸出:

case1... 
case1... 
printing... 
Segmentation fault 

我不明白爲什麼傳遞一個空指針的函數總會引起第一種情況發生。它看起來像指針被傳遞的價​​值,但我不認爲這是怎麼回事。如果我在main()內部的節點上調用malloc(),然後將它傳遞給F(),則第二種情況將會被擊中,但不會是第一種情況。這對我來說至少是有意義的,因爲當節點從main()傳遞到F()時節點永遠不會爲空,但顯然在將節點傳遞給F()之前分配節點意味着F()內的空檢查永遠不會是真的。

我試圖做甚至可能嗎?有沒有辦法通過nF()而它是空的,並讓它按照我想要的方式行事?或者我必須在F()之外分配n並刪除F()裏面的空檢查?

+1

的功能名稱「N」沒有效果應該是功能做什麼範圍內有意義。通常這意味着函數名稱具有活動動詞(通常作爲函數名稱的第一部分)I.E. getValue()calcResult()等。所以這個函數:'F()'是沒有意義的。甚至在我閱讀函數之後,我不確定該函數應該做什麼。 – user3629249

+0

調用函數:'malloc()'和函數系列時,1)不要轉換返回的值,因爲在C中,它是一個'void *',因此可以分配給任何指針,並且投射只會混淆代碼並使維護更困難。 2)函數:'malloc()'和函數系列可能會失敗。因此,請始終檢查(!= NULL)返回的值以確保操作成功,否則失敗將導致代碼引用地址0x0000000000,這將導致未定義的行爲並導致段錯誤事件 – user3629249

+3

您的根本問題是您不知道不明白'X'不是'n'的別名。 '* Y'是'n'的別名。當將'* Y'分配給'X'時,您將'n'的值分配給'X',而不是將'X'作爲別名。 –

回答

2

在爲X分配之後,您需要在函數F()中將其設置爲*Y。否則,F()返回時不會反映出來。

所以我會改變代碼

void F(NODE** Y, int value) 
{ 
    NODE* X = *Y; 

    if(!X) 
    { 
     printf("case1...\n"); 
     X = (NODE*)malloc(sizeof(NODE)); 
     X->Data = value; 

     *Y = X; //set the allocated pointer 
     return; 
    } 
    printf("case2...\n"); 
    X->Next = (NODE*)malloc(sizeof(NODE)); 
    X->Next->Data = value; 
    return; 
} 
+0

快2分鐘...好表演。 –

+0

哇。我不能相信我錯過了這一點。非常感謝你,這讓我瘋狂。這實際上讓我質疑我在學校學到的一切。 – bha

0

在功能F()當在主()包含NULL的 'N';

該代碼未將「n」的內容設置爲指向malloc的內存。

更改包含在局部變量「X」值對在main()