2016-04-22 11 views
0

セグメンテーションフォルトは、最初のifステートメントの*root = x;の挿入機能で発生します。関数は既にレイアウトされており、別のパラメータなどを追加することはできません。私はしばらくこのことに固執していて、それが何であるか分かりません。私は本当に問題が何であるか分からないので、ルートポインタはメモリを割り当てられました。どんな助けでも感謝しています。ツリーの挿入機能でセグメンテーション違反が発生するのはなぜですか?

#include "treeNode.h" 
#include <iomanip> 

template <class V> 
class tree { 
    TreeNode<V> * root; 
    TreeNode<V> * cur; 
    int size; 

    public: 
    // default constructor              
    // by default, the tree is empty            
    tree(){ 
     root = nullptr; 
     size = 0; 
    } 

    // search value x in tree rooted at node t         
    bool treeSearch(V x, TreeNode<V>* t){ 
     if(t == nullptr) return false; 
     if(t->getDatum() == x) return true; 
     return treeSearch(x, t->getLeft()) || treeSearch(x, t->getRight()); 
    } 

    bool treeSearch(V x){ 
     treeSearch(x, root); 
    } 


    // binary search value x in tree rooted at node t       
    bool treeBSearch(V x, TreeNode<V>* t){ 
     if(t == nullptr) return false; 
     if(t->getDatum() == x) return true; 
     if(t->getDatum() > x) 
     return treeBSearch(x, t->getLeft()); 
     else 
     return treeBSearch(x, t->getRight()); 
    } 

    bool treeBSearch(V x){ 
     return treeBSearch(x, root); 
    } 

    // check node t is leaf              
    bool isLeaf(TreeNode<V>* t){ 
     if(t != nullptr && t->getLeft() == nullptr && t->getRight() == nullptr){ 
     return true; 
     }else{ 
     return false; 
     } 
    } 

    // find the height of the tree rooted at node t        
int height(TreeNode<V>* t){ 
     if(t == nullptr) return -1; 
     if(isLeaf(t)) return 0; 
     return 1 + std :: max(height(t->getLeft()), height(t->getRight())); 
    } 

    int height(){ 
     return height(root); 
    } 

    // find the number of nodes of tree rooted at t        
    int nNodes(TreeNode<V>* t){ 
     if(t == nullptr) return 0; 
     return 1 + nNodes(t->getLeft()) + nNodes(t->getRight()); 
    } 

    int nNodes(){ 
     return nNodes(root); 
    } 


    // insert value x to the current tree object         
    void insert(V x){ 
     if(root == nullptr){ 
     *root = x; 
     } 
     else{ 
     cur = root; 
     while(cur != nullptr){ 
      if(cur->getDatum() < x){ 
      if(cur->getLeft() == nullptr){ 
       cur->setDatum(x); 
       cur->setLeft(cur); 
      } 
      else{ 
       cur = cur->getLeft(); 
      } 
      } 
      else{ 
      if(cur->getRight() == nullptr){ 
       cur->setLeft(cur); 
      } 
      else{ 
       cur = cur->getRight(); 
      } 
      } 
     } 
     } 
    } 

    // print out the values of tree rooted at x         
    // it shows the hierarchy of the tree          
    // it will be useful for debugging           
    void print(TreeNode<V> * x, int indent){ 
     if(x == nullptr) return; 
     if (x->getRight() != nullptr) { 
      print(x->getRight(), indent+4); 
     } 
    if (indent != 0) { 
      cout << std::setw(indent) << ' '; 
     } 
     if(x->getRight() != nullptr){ 
      cout << " /\n" << std::setw(indent) << ' '; 
     } 
     cout << x->getDatum() << endl; 
     if (x->getLeft() != nullptr) { 
      cout << std::setw(indent) << ' ' <<" \\\n"; 
      print(x->getLeft(), indent+4); 
     } 
    } 
    void print(){ 
     int count = 0; 
     print(root, count); 
    } 
}; 

これは、各機能のコンストラクタを持つtreeNode.hファイルです。

#include <iostream> 
#include <string> 
#include <algorithm> 
using namespace std; 

template <class T> 
class TreeNode{ 
    T datum; 
    TreeNode<T>* left, * right; 

    public: 
    // constructor with datum value, left and right are nullptr     
    TreeNode(T x){ 
     datum = x; 
     left = nullptr; 
     right = nullptr; 
    } 
    // constructor with datum value, left and right values      
    TreeNode(T x, TreeNode<T>* lft, TreeNode<T>* rgt){ 
     datum = x; 
     left = lft; 
     right = rgt; 
    } 

    //destructor releases left and right nodes, if not nullptr     
    ~TreeNode(){ 
     if (left) { 
      delete left; 
     } 
     if (right) { 
      delete right; 
     } 
    } 

    // get datum value               
    T getDatum(){ 
     return datum; 
    } 

    // get left pointer               
    TreeNode<T>* getLeft(){ 
     return left; 
    } 

    // get right pointer               
    TreeNode<T>* getRight(){ 
     return right; 
    } 
    // set the left pointer              
    void setLeft(TreeNode<T>* p){ 
     left = p; 
    } 
// set the right pointer              
    void setRight(TreeNode<T>* p){ 
     right = p; 
    } 
}; 
+2

:あなたの代わりにNULLポインタを参照解除のために、それに値を割り当てる必要があります - どのようにそれを解決するために

?私はプログラミング科目の教師が、デバッガの使い方を1時間かけて教えてくれることを願っています。いずれにしても、Marcinによる答えは明らかな問題の1つです。 – Cyb3rFly3r

+0

'cur'はクラスメンバー変数ではなく、' insert() 'のローカル変数でなければなりません。 –

+0

'insert()'のあなたのwhileループは決して新しいノードを割り当てません。 –

答えて

5

これは明白である:

if(root == nullptr){ 
    *root = x; 
    ^~~~~ dereferencing null pointer causes UB 
    } 

ルートはnullptrですが、あなたはそれをderefereceを割り当て - これはUB未定義の動作で、この特定の一つは、セグメントフォルトが発生します。あなたのコードにステップし、それが壊れる場所を見つけるために、デバッガを使用してみました

if(root == nullptr){ 
     root = new TreeNode<V>(x); 
    } 
+0

ルートが最初のノードであることを確認してツリーを開始するにはどうすればよいですか? –

+0

@ThomasMolloyでは、*を使用してルートを逆参照するのではなく、単に割り当てます。 – marcinj

+0

"TreeNode * 'に互換性のないタイプ ' int '"に割り当て " –

関連する問題