繁体   English   中英

C++,分配内存,分段错误:11

[英]C++, Allocate memory, Segmentation fault: 11

#include <iostream>

using namespace std;

class Node
{
public:
    Node(int N, Node *l, Node *r);
    int value;    // stored value
    Node *left;   // left node
    Node *right;  // right node
};

Node::Node(int N,  Node *l, Node *r){
    value = N;
    left = l;
    right = r;
}

void insert(Node *x){
    if (x == nullptr) {
        Node newNode(5, nullptr, nullptr);
        *x = newNode;
    }
}

int main(){
    Node *root;
    root = nullptr;
    insert(root);
    cout << root->value << endl;

    return 0;
}

这是二叉搜索树的开始。 在插入函数中,我试图将 nullptr 更改为指向 Node 对象的指针。 当我运行此 C++ 代码时,出现错误:“分段错误:11”。 在做了一些研究之后,我相信我需要(重新)分配内存。 如果可能,如何在插入函数内部分配内存?

你试过运行valgrind吗? 处理这类错误是个好主意(即使您没有看到它们),它有时会在症状显现之前检测到错误(分段错误可能只是早期错误的结果 - 如果它不是正常的调试器)将在发生分段错误的地方停止)。

它直接指向故障:

void insert(Node *x){
    if (x == nullptr) {
        Node newNode(5, nullptr, nullptr);
        *x = newNode;   <<<--- here
    } 
}

所以你基本上检查x是否为空,如果是你尝试取消引用并写入指向的对象? 这听起来真的很糟糕。 你应该做相反的事情-检查,如果它的空你取消引用指针。

首先我假设

if (x == nullptr) {

是错别字吗? 你不是说

if (x != nullptr) {

??

如果它为空,您不应该继续并取消引用它。

您如何修复崩溃实际上取决于您希望 BST 的界面如何。

您正在传入一个nullptr并尝试分配给它。 这行不通。 你不能分配给任何东西。

所以你可以做类似的事情。

#include <iostream>

using namespace std;

class Node
{
public:
    Node(int N, Node *l, Node *r);
    int value;    // stored value
    Node *left;   // left node
    Node *right;  // right node
};

Node::Node(int N,  Node *l, Node *r){
    value = N;
    left = l;
    right = r;
}

void insert(Node *x){
    if (x != nullptr) {
        Node newNode(5, nullptr, nullptr);
        *x = newNode;
    }
}

int main(){
    Node root(2, nullptr, nullptr);
    insert(&root);
    cout << root.value << endl;

    return 0;
}

这里有一个初始对象,分配在堆栈上,您可以在insert分配给它。 如果您使用这种方法,您将浪费一些时间在函数 main 中进行root的初始构造,而您总是要对其进行赋值。

如果您想坚持使用Node堆分配。 将指针传递给要insert指针,例如

#include <iostream>

using namespace std;

class Node
{
public:
    Node(int N, Node *l = nullptr, Node *r = nullptr);
    int value;    // stored value
    Node *left;   // left node
    Node *right;  // right node
};

Node::Node(int N,  Node *l, Node *r)
    : value(N), left(l), right(r)
{}

void insert(Node **x)
{
    if (x != nullptr) 
    {
        Node* n = new Node(5);
        *x = n;
    }
}

int main()
{

    Node *root = nullptr;
    insert(&root);

    if(root)
    {
        cout << root->value << endl;
        delete root;
    }

    return 0;
}

这让插入管理节点的分配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM