2013-04-18 28 views
0

我正在寫一個簡單的函數,它在鏈表的開始處創建一個新節點。當我嘗試執行文件時,我的Windows命令錯誤窗口出現,說「a.exe已停止工作。」如何切換函數內的printf調用,以確定我的代碼是否不會崩潰?

對我而言,神祕之處在於,當我在insertNewNodeAtFront正文中添加printf調用時,代碼將在沒有上述錯誤框的情況下執行。想法?

這裏是源文件:

#include <stdio.h> 


typedef struct NodeTag{ 
    const char* Airport; 
    struct NodeTag * Link;     
    } NodeType; 


void insertNewNodeAtFront(NodeType *, const char*); 


void insertNewNodeAtFront(NodeType * L, const char* str){ 

    NodeType * N; 
    N = L;  
    NodeType * NewFirst; 
    NewFirst->Airport = str; 
    NewFirst->Link = N; 
    L = NewFirst; 
    //printf("L->Airport: %s\n",L->Airport); <---This is the line that magically makes it work. 
} 

int main(){ 
    NodeType * myitinerary; 
    insertNewNodeAtFront(myitinerary,"ONT"); 
    return 0; 
} 
+0

你的調試器說什麼? – 2013-04-18 07:41:33

+0

你怎麼知道「* a.exe已停止工作。*」是一個錯誤? – Maroun 2013-04-18 07:42:22

+0

我沒有真正運行過這個調試器。你對C基於Windows的系統建議哪個? – Thalatta 2013-04-18 07:43:07

回答

1

的代碼deferencing一個未初始化指針,引起undefined behaviour

NodeType * NewFirst; 
NewFirst->Airport = str; 

NewFirst分配內存使用前:

NodeType* newFirst = malloc(sizeof(*newFirst)); 
if (newFirst) 
{ 
} 

printf()正在發揮主導作用未定義行爲的主要表現,但不是原因。

此外,如果你想改變L屬於你需要在指針的地址傳遞給insertNewNodeAtFront()爲C經過值調用者可見(見http://c-faq.com/ptrs/passptrinit.html):

void insertNewNodeAtFront(NodeType** L, const char* str){ 
    /* ...snip... */ 
    *L = NewFirst; 
} 

NodeType* myitinerary = NULL; 
insertNewNodeAtFront(&myitinerary,"ONT"); 
+0

是'if(NewFirst)'檢查分配是否成功? C不能保證malloc會返回一個非NULL指針嗎? – Thalatta 2013-04-18 07:53:58

+0

@ user2276081,是的,它檢查它不是「NULL」。不,'malloc()'不保證成功,如果失敗則返回'NULL'。 – hmjd 2013-04-18 07:54:58

+0

在使用之前,您應該查閱'malloc'的文檔。我不確定什麼文檔適合你使用C的任何實現...在GNU/Linux機器上,man malloc會起作用(除非你決定使用一些瘋狂的編譯器來執行違反C標準的C實現)。如果您可以找到您正在使用的C實現的文檔,則將其用作參考。 – rliu 2013-04-18 08:07:26

0

當你的程序有未定義的行爲,各種事情都可能發生。

具體來說,你從來沒有真正爲您的節點分配內存(有malloc),所以當你開始做這樣的事情NewFirst->Airport = str; - 它覆蓋在內存中(NewFirst是一個未初始化的指針)隨機地址。所有投注都關閉。在繼續實施嘗試之前,您應該搜索實現鏈接列表的示例代碼。

+0

我知道一些關於解除引用內存中我沒有分配的指針的感覺。 – Thalatta 2013-04-18 07:51:49

0

,而不是這個代碼

void insertNewNodeAtFront(NodeType * L, const char* str){ 

     NodeType * N; 
     N = L;  
     NodeType * NewFirst; 
     NewFirst->Airport = str; 
     NewFirst->Link = N; 
     L = NewFirst; 
     //printf("L->Airport: %s\n",L->Airport); <---This is the line that magically makes it work. 
    } 

使用此代碼insertFirst

void insertNewNodeAtFront(NodeType ** L, const char* str){ 


    NodeType * NewFirst = malloc(sizeof(NodeType)); 
    NewFirst->Airport = str; 
    NewFirst->Link = *L; 
    *L = NewFirst; 
    printf("L->Airport: %s\n",(*L)->Airport); 
} 

在主要功能

insertNewNodeAtFront(&myitinerary,"ONT"); 
+0

在這一行'NodeType * myitinerary; insertNewNodeAtFront(myitinerary,「ONT」);'你會傳遞什麼?哪個值?在這一行中,你只是傳遞一些垃圾值(未定義).. – Mani 2013-04-18 07:52:34

1

正如hmjd說,飛機墜毀是通過使用未初始化的內存造成的。當你添加更多代碼的時候,它不會崩潰的原因是這會導致編譯器在內存中移動東西,所以未初始化的變量指向不同的地方。

然而,它仍然不好:你的代碼仍然在內存中佔有一些隨機位置,這很可能會導致另一次崩潰。

相關問題