2011-07-28 73 views
-1

当我执行二叉树并且找不到原因时,代码中出现了分段错误。在执行C中的二叉树时出现分段错误

#include <stdio.h> 
    #include <stdlib.h> 
    struct tree{ 
     int info; 
     struct tree *lptr,*rptr; 
    }; 
    typedef struct tree node; 

    node *create(int, node *); 
    node *insert(node *); 
    void preorder(node *); 
    void inorder(node *); 
    void postorder(node *); 

    int main(){ 
     node *root=NULL; 
     int n,choice=0; 
     while(choice!=6){ 
     printf("\n\n\t\tMENU"); 
     printf("\n\t1:CREATE\n\t2:INSERTION\n\t3:POSTORDER"); 
     printf("\n\t4:INORDER\n\t5:PREORDER\n\t6:EXIT"); 
     printf("\n\n\tEnter your choice:\t"); 
     scanf("%d",&choice); 
     switch(choice){ 
     case 1: 
      printf("\n\tHow many elements to enter\t"); 
      scanf("%d",&n); 
      root=NULL; 
      root=create(n,root); 
     return 0; 
    } 

    node *create(int n, node *root){ 
     int i; 
     for(i=0;i<n;i++) 
      insert(root); 
     return root; 
    }   

    node *insert(node *root){ 
     int val; 
     node *temp, *p, *parent; 
     p=malloc(sizeof(node)); 
     printf("\nEnter data for the node: "); 
     scanf("%d",&val); 
     p->info=val; 
     p->lptr=NULL; 
     p->rptr=NULL; 
     if(root=NULL) 
      root=p; 
     else{ 
      temp=root; 
      while(temp){ 
       parent=temp; 
       if(val<temp->info) 
        temp=temp->lptr; 
       if(val>temp->info) 
        temp=temp->rptr;  
       if(val==temp->info){ 
        printf("Duplicate data!\n"); 
        free(p); 
        break; 
       } 
      } 
      if(!temp&&p){ 
       if(val<parent->info)  //SEGMENTATION FAULT HERE!!! 
        parent->lptr=p; 
       if(val>parent->info) 
        parent->rptr=p; 
      }   
     } 
     return root; 
    } 

    void preorder(node *root){ 
     if(root==NULL) 
      printf("\n\tEMPTY TREE!\n"); 
     else{ 
      printf("%5d",root->info); 
      if(root->lptr) 
       preorder(root->lptr); 
      if(root->rptr) 
       preorder(root->rptr); 
     } 
    } 

    void inorder(node *root){ 
     if(root==NULL) 
       printf("\n\tEMPTY TREE!\n"); 
     else{ 
       if(root->lptr) 
        inorder(root->lptr); 
       printf("%5d",root->info); 
       if(root->rptr) 
        inorder(root->rptr); 
     } 
    } 

    void postorder(node *root){ 
     if(root==NULL) 
      printf("\n\tEMPTY TREE!\n"); 
     else{ 
      if(root->lptr) 
        inorder(root->lptr); 
      if(root->rptr) 
        inorder(root->rptr); 
      printf("%5d",root->info); 
     } 
    } 
+5

GDB是你的朋友去问问他http://www.gnu.org/s/gdb/ –

+0

Stack Overflow不是基本调试技能的替代品。我们不会为你做所有的工作。请尽量至少将您的代码降低到最简单,以便重现问题;这样做你可能会自己发现错误。 – meagar

回答

3

你的问题是,在这些线路上大约10行到您的插入功能:

if(root=NULL) 
    root=p; 

您分配root为NULL,而不是比较为NULL。然后,由于NULL的计算结果为false,因此root不会被分配p。实际上,这两行保证 NULL后执行。你只需要添加一个=,使之像一个比较:

if(root == NULL) 
    root = p; 

这只是题外话,但我建议你周围比较运算把空间。它将使这个错误更加明显,并会作出类似线条:val>parent->info更具可读性,因为该行能够轻松val->parent->info

被误编辑

正如马克在评论中指出的下方,因为==是可交换的,但是=不是,您也可以通过切换操作数的顺序来避免此错误,当您有一个值时。如果你把它放在左边,如(0 == root)(NULL == root)。由于(0 = root)在语法上不正确,因此编译器会为您排除=错误。

+0

非常感谢。我犯了很多次这样的错误... – joansky

+0

@joansky不客气,随时接受我的答案,如果它帮助你:)有一个复选框下投票计数做到这一点。 – Paulpro

+1

@joansky - 如果你犯这样的错误很多,你可以在比较的左边放置数值(例如'if(NULL == root)')的地方使用很多用法。这样,如果您错误地编写了“if(NULL = root)”,编译器会为您捕获它,因为您无法更改常量的值。这是毫无意义的,编译器也同意说'let 0 = root'。 – unpythonic