如何摆脱我的分段错误 [英] How do I get rid of my segmentation fault

查看:73
本文介绍了如何摆脱我的分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 #includebinTree.h
#include< algorithm>
#include< iostream>
#include< iomanip>使用namespace std

;

#ifndef BINSTREE_H
#define BINSTREE_H

模板< class T>
class binSTree:public binTree< t>
{
public:
binSTree(Node< t> * r = NULL):binTree< t> :: binTree(r){}
void insert(const T& x){insert(root,x); }
void remove(const T& x){remove(root,x); }
unsigned size()const {return size(root); }
protected:
Node< t> * 根;
private:
void insert(Node< t> *&,const T&);
void remove(Node< t> *&,const T&);
无符号大小(节点< t> *节点)const {
int l;
int ll;
int lr;
if(!node){l = 0; }
else if(!node-> left&&!node-> right){l = 1; }
else {
ll = size(node-> left);
lr = size(node-> right);
l = ll + lr;
}
返回l; }
节点< t> * pred(节点< t> *&节点){
node = node-> left;
while(node!= NULL){node = node-> right; }
返回节点;}

};

模板< class T>
void binSTree< t> :: insert(节点< t> *& node,const T& x)
{
if(!node){node = new Node< t> (X); }
else if(x< node-> data){insert(node-> left,x); }
else if(x> node-> data){insert(node-> right,x); }
}

模板< class T>
void binSTree< t> :: remove(节点< t> *& node,const T& x)
{
if(x< node-> data){remove (node-> left,x); }
else if(x> node-> data){remove(node-> right,x); }
else if(x == node-> data)
{
if(node-> left == NULL&& node-> right == NULL){删除节点; }
else if(node-> left!= NULL)
{
Node< t> * temp = pred(node);
temp-> left = node-> left;
删除节点;
}
else if(node-> right!= NULL)
{
Node< t> * temp = pred(node);
temp-> right = node-> right;
删除节点;
}
其他
{
节点< t> * temp = pred(node);
node = node-> left;
while(node-> right!= NULL){node = node-> right; }
node = temp;
节点< t> * temp2 = pred(节点);
删除临时;
temp2-> left = node;
}
}
}
#endif

我尝试过:

I我确定这个问题出现在某个地方,我一直在消除循环试图找到问题

不确定从哪里开始

这是一个seg故障核心转储

解决方案

Quote:

我如何摆脱我的分段错误



您的代码不是自治的,我们无法重现问题,只是猜测。

使用调试器检查变量,并检查任何空指针都是预期的NULL。

-----

学会正确缩进代码,显示其结构,有助于阅读和理解。

  #include      binTree.h 
#include < 算法 >
#include < iostream >
# include < iomanip >

使用 命名空间标准;

#ifndef BINSTREE_H
#define BINSTREE_H

模板< class T>
class binSTree: public binTree< t>
{
public
binSTree(Node< t> * r = NULL):binTree< t> :: binTree( r){}
void insert( const T& x){insert(root,x) ); }
void remove( const T& x){remove(root,x); }
unsigned size() const { return 大小(根); }
受保护
节点< t> * 根;
private
void insert(Node< t> *& ;,, const T&);
void remove(节点< t> *&, const T&);
无符号大小(节点< t> *节点) const {
int l;
int ll;
int lr;
if (!node)
{
l = 0 ;
}
else if (!node-> left&& !node-> right)
{
l = 1 ;
}
else {
ll = size(node-> left);
lr = size(node-> right);
l = ll + lr;
}
return l;
}
节点< t> * pred(节点< t> *&节点){
node = node-> left;
while (node!= NULL)
{
node = node-> right;
}
返回节点;}

};

模板< class T>
void binSTree< t> :: insert(节点< t> *& node, const T& x)
{
if (!node)
{
node = new 节点< t>(x);
}
else if (x< node-> data)
{
insert(node-> left,x);
}
其他 如果(x> node-> data)
{
insert(node-> right,x);
}
}

模板< class T>
void binSTree< t> :: remove(节点< t> *& node, const T& x)
{
if (x< node-> data)
{
remove (node-> left,x);
}
其他 如果(x> node-> data)
{
remove(node-> right,x);
}
else if (x == node-> data)
{
if (node-> left == NULL&& node-> right == NULL)
{
删除节点;
}
else if (node-> left!= NULL)
{
节点< t> * temp = pred(节点);
temp-> left = node-> left;
删除节点;
}
else if (node-> right!= NULL)
{
节点< t> * temp = pred(节点);
temp-> right = node-> right;
删除节点;
}
else
{
节点< t> * temp = pred(node);
node = node-> left;
while (node-> right!= NULL)
{
node = node-> right;
}
node = temp;
节点< t> * temp2 = pred(节点);
delete temp;
temp2-> left = node;
}
}
}
#endif



专业程序员的编辑器具有此功能和其他功能,如括号匹配和语法高亮。

Notepad ++主页 [ ^ ]

ultraedit [ ^ ]


Quote:

调试器只是告诉我它崩溃了if(x< node-> ;数据)和那个陈述应该是对的吗?



因为你没有进行健全性检查:

  if (!node)
{
// 处理错误
}

断言(节点) ); 



无论如何,正如其他人所建议的那样,你必须使用调试器来发现错误情况发生的原因。


你的 root 成员未初始化。

我想它应该设置为构造函数中传递的值:

< pre lang =c ++> binSTree(节点< t> * r = NULL):binTree< t> :: binTree(r),root(r){}



您还必须设置传递的 remove()函数中删除指向 NULL 的指针:

 // ... 
节点< t> * temp = pred(节点);
temp-> left = node-> left;
删除节点;
//每次删除后插入此行
node = NULL;
// ...



你的 pred()函数总是返回 NULL

节点< t> * pred(节点< t> *&节点)
{
/ /这里缺少检查NULL
node = node-> left;
while(node!= NULL)
node = node-> right;
//节点在这里始终为NULL!
返回节点;
}

该函数也在更改内容,因为 node 是通过引用传递的。最好传递一个 const 指针,并使函数 const



最后你应该 - 如已经建议的那样 - 总是检查是否传递节点指针是 NULL 。但是对于非空但无效的指针(同时没有初始化或删除),这些检查将失败(表示成功)。


#include "binTree.h"
#include <algorithm>
#include <iostream>
#include <iomanip>

using namespace std;

#ifndef BINSTREE_H
#define BINSTREE_H

template <class T>
class binSTree : public binTree <t>
{
public:
binSTree( Node <t> *r = NULL ): binTree<t>::binTree(r) {}
void insert(const T& x){ insert(root, x); }
void remove(const T& x){ remove(root, x); }
unsigned size() const{ return size(root); }
protected:
Node <t> * root;
private:
void insert(Node <t>*&, const T& );
void remove(Node <t> *&, const T&);
unsigned size( Node<t>* node) const{
int l;
int ll;
int lr;
if(!node){ l = 0; }
else if(!node->left && !node->right){ l = 1; }
else{
ll = size(node->left);
lr = size(node->right);
l=ll+lr;
}
return l; }
Node <t>* pred( Node<t>*& node){
node = node->left;
while(node != NULL){ node = node->right; }
return node;}

};

template <class T>
void binSTree<t>::insert(Node <t>*& node, const T& x)
{
if(!node){ node = new Node<t>(x); }
else if( x < node->data ){ insert(node->left, x); }
else if( x > node->data ){ insert(node->right, x); }
}

template <class T>
void binSTree<t>::remove(Node <t> *& node, const T& x)
{
if(x < node->data){ remove(node->left, x); }
else if(x > node->data){ remove(node->right, x); }
else if(x == node->data)
{
if(node->left == NULL && node->right == NULL){ delete node; }
else if( node->left != NULL )
{
Node<t>* temp = pred(node);
temp->left = node->left;
delete node;
}
else if(node->right != NULL )
{
Node<t>* temp = pred(node);
temp->right = node->right;
delete node;
}
else
{
Node<t>* temp = pred(node);
node = node->left;
while(node->right != NULL){ node = node->right; }
node = temp;
Node<t>* temp2 = pred(node);
delete temp;
temp2->left = node;
}
}
}
#endif

What I have tried:

I'm sure the problem is here somewhere, I've mostly been eliminating loops trying to find the problem

not sure where to start

it's a seg fault core dump

解决方案

Quote:

How do I get rid of my segmentation fault


Your code is not autonomous, we can't reproduce the problem, just guess.
Use the debugger to inspect variables, and check that any empty pointer is NULL as expected.
-----
Learn to indent properly your code, it show its structure and it helps reading and understanding.

#include "binTree.h"
#include <algorithm>
#include <iostream>
#include <iomanip>

using namespace std;

#ifndef BINSTREE_H
#define BINSTREE_H

template <class T>
class binSTree : public binTree <t>
  {
    public:
      binSTree( Node <t> *r = NULL ): binTree<t>::binTree(r) {}
      void insert(const T& x){ insert(root, x); }
      void remove(const T& x){ remove(root, x); }
      unsigned size() const{ return size(root); }
    protected:
      Node <t> * root;
    private:
      void insert(Node <t>*&, const T& );
      void remove(Node <t> *&, const T&);
      unsigned size( Node<t>* node) const{
        int l;
        int ll;
        int lr;
        if(!node)
        {
          l = 0;
        }
        else if(!node->left && !node->right)
        {
          l = 1;
        }
        else{
          ll = size(node->left);
          lr = size(node->right);
          l=ll+lr;
        }
        return l;
      }
      Node <t>* pred( Node<t>*& node){
        node = node->left;
        while(node != NULL)
        {
          node = node->right;
        }
      return node;}

    };

    template <class T>
    void binSTree<t>::insert(Node <t>*& node, const T& x)
      {
        if(!node)
        {
          node = new Node<t>(x);
        }
        else if( x < node->data )
        {
          insert(node->left, x);
        }
        else if( x > node->data )
        {
          insert(node->right, x);
        }
      }

    template <class T>
    void binSTree<t>::remove(Node <t> *& node, const T& x)
      {
        if(x < node->data)
        {
          remove(node->left, x);
        }
        else if(x > node->data)
        {
          remove(node->right, x);
        }
        else if(x == node->data)
        {
          if(node->left == NULL && node->right == NULL)
          {
            delete node;
          }
          else if( node->left != NULL )
          {
            Node<t>* temp = pred(node);
            temp->left = node->left;
            delete node;
          }
          else if(node->right != NULL )
          {
            Node<t>* temp = pred(node);
            temp->right = node->right;
            delete node;
          }
          else
          {
            Node<t>* temp = pred(node);
            node = node->left;
            while(node->right != NULL)
            {
              node = node->right;
            }
            node = temp;
            Node<t>* temp2 = pred(node);
            delete temp;
            temp2->left = node;
          }
        }
      }
      #endif


Professional programmer's editors have this feature and others ones such as parenthesis matching and syntax highlighting.
Notepad++ Home[^]
ultraedit[^]


Quote:

Debugger just told me it's crashing at if(x < node->data) and that statement should be right?


because you didn't perform a sanity check:

if ( ! node )
{
  // handle error
}

or

assert(node);


Anyway, as others suggested, then you have to use the debugger to discover why the buggy condition occurred.


Your root member is not initialised.
I guess it should be set to the value passed in the constructor:

binSTree( Node <t> *r = NULL ): binTree<t>::binTree(r), root(r) {}


You must also set the passed Node pointer to NULL after deleting it in the remove() function:

// ...
Node<t>* temp = pred(node);
temp->left = node->left;
delete node;
// Insert this line after each delete
node = NULL;
// ...


Your pred() function returns always NULL:

Node <t>* pred( Node<t>*& node)
{
    // Missing check for NULL here
    node = node->left;
    while(node != NULL)
        node = node->right; 
    // node is always NULL here!
    return node;
}

The function is also changing the content because node is passed by reference. It would be better to pass a const pointer instead and make the function const too.

Finally you should - as already suggested - always check if passed Node pointers are NULL. But these checks will fail (indicate success) for non-null but invalid pointers (not initialised or deleted meanwhile).


这篇关于如何摆脱我的分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆