在 C++ 中构建二叉树后的分段错误
Segmentation Fault after building Binary Tree in C++
我用 C++ 构建了一个二叉树。构建树后,出现分段错误。不知道为什么。
void buildTree(binTreeNode * r, int i){
if(i > 0)
{
if(r != NULL)
{
if(r->left == NULL)
{
r->left = new struct binTreeNode;
r->left->item = r->item + 1;
}
if(r->right == NULL)
{
r->right = new struct binTreeNode;
r->right->item = r ->item + 1;
}
}
i--;
buildTree(r->left, i);
buildTree(r->right, i);
}
return;
}
我在main中设置初始id为1
问题很可能是由于您初始化了 struct binTreeNode
个实例。与 Java 或 Python 等语言不同,C++ 并不总是 将所有 attributes/members 初始化为零,而是取决于 on semantics 何时初始化做吧。
那么,幕后发生了什么?
当你调用 new your_type;
时,操作系统会给你一块内存。您获得的唯一保证是分配的内存 至少 your_type
的大小。如果你(非常¹⁰)幸运,那块内存被设置为零。然而,更有可能的是,这块内存之前被另一个写入它的进程使用(并释放)。因此它包含随机数据。
实际上,这意味着 binTreeNode->left
可能 是 NULL
,但这 不能保证 . binTreeNode->right
.
也是如此
如何修复:
定义一个构造函数,明确设置实例的初始值。对于您的情况,这样的事情就足够了:
struct binTreeNode {
int id;
binTreeNode* left;
binTreeNode* right;
binTreeNode()
: id{0}
, left{NULL}
, right{NULL}
{}
};
如果您从未听说过构造函数(以防万一):
构造函数是特殊方法,在创建类型的新实例时调用。
作为附加说明,使用 C++11 中引入的 nullptr
而不是 NULL
。
您遇到分段错误的原因可能是当您创建一个新节点时,您只初始化了它的数据成员 id
,而没有初始化它的另外两个数据成员 left
和 right
。因此,当您在这个新节点上调用 buildTree
时,这两个指针将是 wild pointers。任何取消引用野指针的尝试都可能导致分段错误。
这个答案假定 binTreeNode
是一个简单的 C 风格 struct
。如果它是一个带有初始化所有数据成员的构造函数的 class,那么这个答案是不正确的。因为你没有postbinTreeNode
的定义,所以我不可能知道。
我用 C++ 构建了一个二叉树。构建树后,出现分段错误。不知道为什么。
void buildTree(binTreeNode * r, int i){
if(i > 0)
{
if(r != NULL)
{
if(r->left == NULL)
{
r->left = new struct binTreeNode;
r->left->item = r->item + 1;
}
if(r->right == NULL)
{
r->right = new struct binTreeNode;
r->right->item = r ->item + 1;
}
}
i--;
buildTree(r->left, i);
buildTree(r->right, i);
}
return;
}
我在main中设置初始id为1
问题很可能是由于您初始化了 struct binTreeNode
个实例。与 Java 或 Python 等语言不同,C++ 并不总是 将所有 attributes/members 初始化为零,而是取决于 on semantics 何时初始化做吧。
那么,幕后发生了什么?
当你调用 new your_type;
时,操作系统会给你一块内存。您获得的唯一保证是分配的内存 至少 your_type
的大小。如果你(非常¹⁰)幸运,那块内存被设置为零。然而,更有可能的是,这块内存之前被另一个写入它的进程使用(并释放)。因此它包含随机数据。
实际上,这意味着 binTreeNode->left
可能 是 NULL
,但这 不能保证 . binTreeNode->right
.
如何修复:
定义一个构造函数,明确设置实例的初始值。对于您的情况,这样的事情就足够了:
struct binTreeNode {
int id;
binTreeNode* left;
binTreeNode* right;
binTreeNode()
: id{0}
, left{NULL}
, right{NULL}
{}
};
如果您从未听说过构造函数(以防万一): 构造函数是特殊方法,在创建类型的新实例时调用。
作为附加说明,使用 C++11 中引入的 nullptr
而不是 NULL
。
您遇到分段错误的原因可能是当您创建一个新节点时,您只初始化了它的数据成员 id
,而没有初始化它的另外两个数据成员 left
和 right
。因此,当您在这个新节点上调用 buildTree
时,这两个指针将是 wild pointers。任何取消引用野指针的尝试都可能导致分段错误。
这个答案假定 binTreeNode
是一个简单的 C 风格 struct
。如果它是一个带有初始化所有数据成员的构造函数的 class,那么这个答案是不正确的。因为你没有postbinTreeNode
的定义,所以我不可能知道。