我正在使用C ++编写二进制搜索树。在我的程序上运行gdb(我收到段错误)后,我收到以下错误报告:
#0 0x08049058 in searchTree::tree_node<int>::getLeft (this=0x0) at bst.hxx:75
#1 0x08048ed8 in searchTree::bst_iter<int>::operator++ (this=0xbffff4b4) at bst.hxx:586
#2 0x08048a72 in main () at projectmain.cxx:29
#0错误是指我的getLeft()函数,如下所示:
template <typename T>
inline tree_node<T>* tree_node<T>::getLeft() const
{
return tree_node<T>::left_; //note that left_ is of type tree_node<T>*
}
#1错误是指我的迭代器中定义的operator ++,如下所示:
bst_iter<T>& operator++()
{ //note that s is a stack of tree_node<T>*
tree_node<T> *p = pos_->getRight();
s.push(p);
for(p=p->getLeft(); p!=NULL; p=p->getLeft())
{
s.push(p);
}
pos_ = s.top();
s.pop();
return *this;
}
#2错误是指我的主程序,其中我包含的文件包含我对tree_node,binaryTree,bst_iter和bst_citer的定义(此时不存在,所以不是问题)。
bst_iter<int> i = treeTime.begin(); //treeTime is our tree
bst_iter<int> iEnd = treeTime.end();
for(; i != iEnd ;++i) //crash
{
cout<<*i<<" ";
}
template <typename T>
inline bst_iter<T> binaryTree<T>::begin()
{
return bst_iter<T>(root_);
}
template <typename T>
inline bst_iter<T> binaryTree<T>::end()
{
return bst_iter<T>(0);
}
我不完全确定导致错误的原因。我相信++()正试图访问一个尚未定义的区域,但我不确定它为什么这样做或如何阻止它...我试图阻止代码,作为代码差不多有800行,但如果需要更多信息,请告诉我......
答案 0 :(得分:1)
你是如何初始化for循环迭代器的?如果它开始无效,那么这将解释事情。
答案 1 :(得分:0)
如果pos _-&gt; getRight()返回空指针,则可能发生这种情况。
由于您在结果上调用了getLeft而没有将其检查为null,因此最终会得到一个null的this指针。
答案 2 :(得分:0)
正如您在gdb back trace中看到的那样,最终在NULL指针上调用getLeft()
。即它的此指针为NULL。
在operator++
内的循环中,您在getLeft()
上调用p
,而不先检查它是否为NULL。即如果getRight()
返回NULL,你就会崩溃。
你可能想做这样的事情:
bst_iter<T>& operator++()
{ //note that s is a stack of tree_node<T>*
tree_node<T> *p = pos_->getRight();
if (p == NULL) p = pos_;
else s.push(p);
for(p=p->getLeft(); p!=NULL; p=p->getLeft())
{
s.push(p);
}
// TODO: what if s is empty?
pos_ = s.top();
s.pop();
return *this;
}
这不是一个完整的解决方案。它取决于你的end()
迭代器状态应该是什么。
但是,似乎有更有效,更直观的方式来实现operator++
。例如,STL允许您删除树中的条目,并且只使指向该节点的迭代器无效。在您的情况下,所有迭代器都必须失效。