CPP 中的分段错误(核心已转储)

Segmentation fault(core dumped) in CPP

我有点困惑。我将其缩小为:

为什么会有这条线:

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;
}

您在这里使用 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++){

在不修改你的代码的情况下,我认为是这样的:

Node *root, *rootSafe = NULL;

并没有按照您的想法行事。您认为它会将两者都设置为 NULL 吗?它没有。 root 获得一些随机值,rootSafe 获得 NULL。

这可能是您真正想要的:

Node *root = NULL, *rootSafe = NULL;

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

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

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

Node *root, *rootSafe = NULL;
Node *rootSafe, *root = NULL;

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

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