由于构造函数,即将出现分段错误

Posted

技术标签:

【中文标题】由于构造函数,即将出现分段错误【英文标题】:Segmentation fault is coming due to constructor 【发布时间】:2013-04-15 09:23:08 【问题描述】:

我编写了一个 C++ 代码来构建二叉搜索树。代码编译正确,但是当我尝试运行可执行文件时,它给出了分段错误。以下是我的代码:

    #include <iostream>

using namespace std;

struct Node
    Node *parent, *right, *left; 
    int data;
;

class bst
    private:
    Node* root;

    public:
        bst (int data);
        void insert (Node * node, int data);
        void insert (int data);
        Node * search (int data);
        Node * search (Node * node, int data);
        // remove (Node * node, int data);
;

bst::bst (int data)
    root -> data = data;


void bst::insert (Node * node, int data)
    if (node == NULL)
        node -> data = data;
    
    else if (data < node -> data)
        insert (node -> left, data);
    
    else if (data > node -> data)
        insert (node -> right, data);
    


void bst::insert (int data)
    insert (root, data);


Node * bst::search (Node * node, int data)
    if (node == NULL || node -> data == data)
        return node;
    else if (data < node -> data)
        return search (node -> left, data);
    else if (data > node -> data)
        return search (node -> right, data);


Node * bst::search (int data)
    search (root, data);


int main()
    cout << "main entry\n";
    bst __bst (10);
    cout << "new causing problem\n";
    bst bst2(1);
//  bst *my_bst = new bst(10);
    cout << "tree created\n";
/*  my_bst -> insert(32);
    my_bst -> insert(3);
    my_bst -> insert(36);
    my_bst -> insert(93);
    my_bst -> insert(23);
    cout << "insertion completed\n";

    if (my_bst -> search(4) == NULL )
        cout << "4 does not exist\n";
    if (my_bst -> search(36) != NULL)
        cout << "36 exists in tree\n";
*/  return 0;

在调试问题时,我发现了一个有趣的观察结果。当 main 函数仅包含 bst __bst (10); 对象定义和之后的 "new cause problem\n" 注释时,它不会打印任何内容。所以我假设第一个对象定义引起了问题。但是当我把 bst bst2(1);bst *my_bst = new bst(10); 放在主要位置时,分段错误再次发生但不是在 之前打印新的导致问题\n"。所以执行确实达到了这一点。所以在这种情况下,第一个对象定义没有造成任何问题。

谁能说出导致分段错误的原因以及为什么会发生这种奇怪的事情。

编辑: 正如你们所有人指出的那样,我试图在构造函数代码期间取消引用 NULL 指针,我做了建议的更改并且代码运行良好。但是我有一个类似的程序,即使没有这些更改也能正常工作。下面是代码:

#include <iostream>

using namespace std;

struct Name
    string first_name;
    string last_name;
;

class Person
    public:
    Person (string first_name, string last_name)
            name -> first_name = first_name;
            name -> last_name = last_name;
       

    int get_age()
            return age;
       

    void set_age (int new_age)
            age = new_age;
       

    string get_first_name()
            return name -> first_name;
       

    string get_last_name()
            return name -> last_name;
       

    private:
    Name * name;
    int age;
;

int main () 
    Person prince ("Prince", "Kumar");
    cout << prince.get_first_name() << endl;
    cout << prince.get_age() << endl;
    return 0;

在这种情况下,程序运行良好。 Name 的默认构造函数是否为 name 指针分配了一些空间。我知道它将 0 值分配给数字类型,将 NULL 分配给指针、对象和字符串。我说的对吗?

【问题讨论】:

旁注:在 C++ 中,任何包含 __ 或以 _ 开头后跟大写字母的标识符都是保留的。你不应该使用它们。 不要忘记刷新流(std::flushstd::endl),否则无法保证您会真正看到任何输出。 @sftrabbit,我相信\n 已经做到了。 @Shahbaz:你想到了endl。流应在其析构函数中刷新。 @Wug '\n' 可能会或可能不会刷新标准输出(它的实现已定义),但endl 保证将刷新输出。这就是'\n'endl 之间的区别。 【参考方案1】:
private:
    Node* root;

root 没有在构造函数中初始化

bst::bst (int data)
    root -> data = data;

【讨论】:

【参考方案2】:

当树为空时,您在 insert() 中取消引用空指针

【讨论】:

【参考方案3】:

在您的构造函数中,您正在取消引用作为指针的根,而没有为其分配任何内存,这是undefined behavior:

bst::bst (int data)
  root -> data = data;

这样就足够了:对于这个问题

bst::bst (int data) : root( new Node ) 
                      ^^^^^^^^^^^^^^^^ 

  root -> data = data;

只需使用初始化列表来分配内存。你的insert 方法也有同样的问题:

if (node == NULL)
    node -> data = data;

解决方法类似:

node = new Node ;
node->data = data ;

尽管您需要正确初始化rightleftparent,但要使其正常工作,我建议在Node 中为此使用构造函数:

Node() : parent(NULL), right(NULL), left(NULL) 

这些修复似乎让您获得了一个工作程序。

【讨论】:

你的意思是“根(新节点)”? @AndreyVolk 是的,你是对的,我一定是编辑时打错了,谢谢。 感谢您的及时回复。我是面向对象编程的新手。但我仍然对问题的第二部分感到困惑。由于问题出在构造函数中,程序应该在第一次构造函数调用之后结束。但它的打印“新引起的问题\n”。这似乎很奇怪。 @PrinceKumar 好吧,这是未定义的行为,这意味着任何事情都可能发生,包括不工作但不崩溃 哦,好的。感谢您的帮助。

以上是关于由于构造函数,即将出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章

构造函数中的分段错误不明确

带有 QWidget 的分段错误构造函数。 Qt/C++

构造函数内部变量的定义会导致分段错误

vector<pair<int, unordered_set<int>>> 在为 pair 提供默认构造函数参数时给出分段错误

具有显式构造函数的类是不是需要在 emplace 中使用分段构造?

为啥这个向量代码会出现分段错误?