2016-02-29 83 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编码,请看看。 –