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++ 代码时,我得到错误:"Segmentation fault: 11"。在做了一些研究之后,我相信我需要(重新)分配内存。如果可能的话,如何在插入函数中分配内存?
你试过运行valgrind
吗?对于这些类型的错误(即使您没有看到它们)是个好主意,它有时会在症状变得可见之前检测到错误(分段错误可能只是早期错误的结果 - 如果它不是普通的调试器将在发生分段错误的地方停止)。
直接指向错误:
void insert(Node *x){
if (x == nullptr) {
Node newNode(5, nullptr, nullptr);
*x = newNode; <<<--- here
}
}
所以您基本上检查 x
是否为 null,如果是,您尝试取消引用并写入指向的对象?这听起来真的很糟糕。你应该做相反的事情 - 检查它是否为空你做 not 取消引用指针。
首先我想
if (x == nullptr) {
是不是打错了?你不是说
if (x != nullptr) {
??
如果它为 null,则不应继续并取消引用它。
如何修复崩溃实际上取决于您希望 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;
}
这让插入管理节点的分配。
#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++ 代码时,我得到错误:"Segmentation fault: 11"。在做了一些研究之后,我相信我需要(重新)分配内存。如果可能的话,如何在插入函数中分配内存?
你试过运行valgrind
吗?对于这些类型的错误(即使您没有看到它们)是个好主意,它有时会在症状变得可见之前检测到错误(分段错误可能只是早期错误的结果 - 如果它不是普通的调试器将在发生分段错误的地方停止)。
直接指向错误:
void insert(Node *x){
if (x == nullptr) {
Node newNode(5, nullptr, nullptr);
*x = newNode; <<<--- here
}
}
所以您基本上检查 x
是否为 null,如果是,您尝试取消引用并写入指向的对象?这听起来真的很糟糕。你应该做相反的事情 - 检查它是否为空你做 not 取消引用指针。
首先我想
if (x == nullptr) {
是不是打错了?你不是说
if (x != nullptr) {
??
如果它为 null,则不应继续并取消引用它。
如何修复崩溃实际上取决于您希望 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;
}
这让插入管理节点的分配。