【问题标题】:Segmentation fault(core dumped) in CPPCPP 中的分段错误(核心转储)
【发布时间】:2021-07-07 16:18:42
【问题描述】:

我有点困惑。我把它缩小到:

为什么会有这条线:

Node *root, *rootSafe = NULL;

给出错误:

Segmentation fault(core dumped)

虽然只是像下面这样切换它:

Node *rootSafe, *root = NULL;

完美运行。

这是代码,你可以测试一下。

#include <iostream>
using namespace std;
struct Node{
    int data;
    Node *left, *right;
    Node(int d){
        this->data = d;
        this->left = this->right = NULL;
    }
};
Node *newNode(int d){
    Node *temp = (Node *)malloc(sizeof(Node));
    temp->data = d;
    temp->left = temp->right = NULL;
    return temp;
}
void printInorder(Node *root){
    if(root == NULL){
        return;
    }
    else{
        printInorder(root->left);
        cout << "--" << root->data;
        printInorder(root->right);
    }
}
int main()
{
    //cout << "Hello World";
    Node *rootSafe, *root = NULL;
    int arr[] = {5, 3, 1, 4, 6};
    int sizeArr = sizeof(arr)/sizeof(arr[0]);
    
    for(auto i = 0; i < sizeArr; i++){
        if(root == NULL){
            rootSafe = newNode(arr[i]);
            root = rootSafe;
        }
        else{
            while(root != NULL){
                if(arr[i] < root->data){//Move left
                    if(root->left == NULL){
                        root->left = newNode(arr[i]);
                        root = NULL;
                    }
                    else{
                        root = root->left;
                    }
                }
                else{//Move right
                    if(root->right == NULL){
                        root->right = newNode(arr[i]);
                        root = NULL;
                    }
                    else{
                        root = root->right;
                    }
                }
            }
        }
        root = rootSafe;
    }
    
    cout << "\n Print Inorder: ----"; printInorder(rootSafe);
    return 0;
}

【问题讨论】:

  • 为什么在 C++ 中使用 malloc?
  • 只是测试,我可以不用它,因为 struct Node 有构造函数。
  • 所以,这有什么不寻常的地方,你应该初始化 all 声明的指针是安全的,即Node *root = NULL, *rootSafe = NULL;。顺便说一句,这是 C 代码,而不是 C++。 C++ 使用nullptr 而不是NULL
  • 未初始化的变量保留其内存单元中的任何值,这使得 *root 在错误情况下具有值。
  • 我明白了,我犯了几个错误。感谢 sklott 的指正!

标签: c++ pointers compiler-errors segmentation-fault


【解决方案1】:

你在这里使用root

        if(root == NULL){

您的原始声明

Node *root, *rootSafe = NULL;

不初始化root,留下不确定的值。因此,带有一些随机无效值的root可能会被取消引用,并可能导致分段错误。

为避免这种情况,您应该在使用之前初始化root

可以在声明中完成:

Node *root = NULL, *rootSafe = NULL;

或者在循环之前:

    root = NULL;
    for(auto i = 0; i < sizeArr; i++){

【讨论】:

    【解决方案2】:

    不用摆弄你的代码,我认为:

    Node *root, *rootSafe = NULL;
    

    不做你认为它做的事。你认为它将两者都设置为 NULL 吗?它没有。 root 得到一些随机值,rootSafe 得到 NULL。

    这可能是你真正想要的:

    Node *root = NULL, *rootSafe = NULL;
    

    坦率地说,我个人讨厌(并且在某些工作场所违反编码约定)在同一行指定多个变量。你不会在我的代码中找到这个。相反,您会看到:

    Node * root = nullptr;
    Node * rootSafe = nullptr;
    

    还要注意,在现代 C++ 中,NULL 不是指针。养成使用 nullptr 的习惯。

    【讨论】:

      【解决方案3】:
      Node *root, *rootSafe = NULL;
      Node *rootSafe, *root = NULL;
      

      第一行未初始化 root。这会导致访问 root 时出现未定义的行为。

      第二行未初始化 rootSafe,但后来初始化了 var rootSafe = newNode(arr[i]);

      【讨论】:

        猜你喜欢
        • 2016-12-28
        • 2021-01-02
        • 2015-06-25
        • 2021-06-03
        相关资源
        最近更新 更多