2016-02-29 134 views
2

由於我不明白爲什麼我會得到一個,所以顯然我對分割錯誤感到困惑。我試圖遍歷一個我已經構建的樹,我已經測試並且工作正常。但是,當我嘗試運行以下功能時,出現分段錯誤。任何人都可以告訴我我在哪裏以及爲什麼會出現分段錯誤,以便將來避免這種情況?謝謝。C - 爲什麼會出現分段錯誤?

void traverse(Node *root) 
{ 
    Node *pointer; 
    Node *pre; 

    if(root == NULL) 
     return; 

    pointer = pre; 

    while(pointer != NULL) 
    { 
     if(pointer->leftChild != NULL) 
      pointer = pointer->rightChild; 
     else 
     { 
      pre = pointer->leftChild; 

      while(pre->rightChild != NULL && pre->rightChild != pointer) 
       pre = pre->rightChild; 

      if(pre->rightChild != NULL) 
      { 
       pre->rightChild = pointer; 
       pointer = pointer->leftChild; 
      } 
      else 
      { 
       pre->rightChild = pointer; 
       pointer = pointer->leftChild; 
      } 
     } 
    } 
} 
+4

你永遠不會初始化'pointer'或'pre',並且基本上完全忽略了作爲參數傳入的'root'節點,所以你試圖在undefined/uninitialized結構中解引用指針。 –

+1

同樣在第13行,您正在檢查左側節點是否爲空,然後您訪問正確的節點。 – martin

+0

在C中始終正確初始化任何變量,代碼在寫入之前將讀取它。 – alk

回答

2

你必須initialze Node *pre = NULL;Node *pointer = root;。您沒有初始化pre,但分配了pointer = pre;

除了形成這個你應該改變這樣的:

if (pointer->rightChild!= NULL) 
      // ^^^^^^^^^^ change leftChild to rightChild 
    pointer = pointer->rightChild; 

如果樹的節點沒有指向父節點,它通常使用遞歸函數通過樹遍歷:

void traverse(Node *root) 
{ 
    if (root == NULL) 
     return; 

    traverse(root->leftChild); 

    // do somethig with root 

    traverse(root->rightChild); 
} 

請注意,遞歸函數的參數取代了從葉節點返回到根節點所必需的堆棧。

3

指針最初包含垃圾值,因爲您沒有在代碼中初始化它。

Node *pointer; 
Node *pre; 

,因爲它們含有垃圾值,他們可能不會指向NULL,他們將被指向哪裏會被分配給其他一些資源,不能在下面的行導致分段故障進行訪問。

if(pointer->leftChild != NULL) 
     pointer = pointer->rightChild; 

您需要初始化您的指針或分配給它的輸入參數。

編輯

還有一個問題,我可以在你的代碼中觀察到在if-else條件。 在您的if條件中,您正在檢查if(pointer->leftChild != NULL) ,因此如果此條件爲false(即pointer->leftChild = NULL),則會落入else區塊,您在此處指定;

pre = pointer->leftChild; // Here pre is always NULL 

因此,如果您嘗試進一步使用它,它會拋出異常,從而導致您的代碼崩潰。

+0

謝謝。我初始化了pointer = root和pre = NULL。但是,我仍然在犯錯。 – user3713899

+0

你可以發佈調用這個函數的代碼嗎? –

+0

@ user3713899編碼,請看看。 –