g++ -O2 标志给出分段错误
g++ -O2 flag giving segmentation fault
下面的程序是一个 bst 树,它在未优化的设置下工作正常,但在特殊情况下会产生 SIGSEGV。由于我的调试技能没有扩展到汇编,所以我可以使用一些输入来确定导致此错误的原因。下面是完整的代码,因此可以重现。没有什么特别的,有一个节点结构来保存节点数据,一个简单的插入操作和一个确认树高度的方法。
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct avl_tree_node //node data
{
int data;
int balance{0};
avl_tree_node *left{NULL};
avl_tree_node *right{NULL};
avl_tree_node *parent{NULL};
}node;
class avl
{
private:
node *root;
int get_height(node *head) //calculates the height
{
if (head == NULL)
return -1;
int l_height = get_height(head->left);
int r_height = get_height(head->right);
if (l_height > r_height)
return l_height+1;
return r_height+1;
}
void unbalanced_insert(node *head, int item); //method definition for a simple insert
public:
avl(int data)
{
root->data = data;
root->parent = NULL;
root->left = NULL;
root->right = NULL;
}
int height() //gives the height
{
return get_height(root);
}
void unbalanced_insert(int item) //wrapper
{
unbalanced_insert(root, item);
}
};
void avl::unbalanced_insert(node *head, int item) //inserts node to the tree
{
//cout << "stepped" << endl;
if (item > head->data)
{
if (head->right == NULL)
{
head->right = (node*)malloc(sizeof(node));
head->right->data = item;
head->right->parent = head;
head->right->left = NULL;
head->right->right = NULL;
head->balance = 1;
return;
}
unbalanced_insert(head->right, item);
head->balance++;
return;
}
else
{
if (head->left == NULL)
{
head->left = (node*)malloc(sizeof(node));
head->left->data = item;
head->left->parent= head;
head->left->left = NULL;
head->left->right = NULL;
head->balance = -1;
return;
}
unbalanced_insert(head->left, item);
head->balance--;
return;
}
}
int main()
{
avl a(0);
for (int i = 1; i < 5; i++) //works until i < 4
{
a.unbalanced_insert(i);
}
cout << a.height() << endl;
return 0;
}
在正常情况下,我很高兴这适用于未优化的标志,但我必须使用特定的标志来构建它。其中之一是 -O2
标志。分段错误发生在 avl a(0)
对象构造和 main 中的 for 循环之间。该错误似乎还取决于 for 循环的布尔检查。如果 i < 4
并执行: g++ avl.cpp -g -O2 -o program && ./program
一个明显的问题,它发生在 main
中的第一个函数调用中,即 avl a(0)
:
root->data = data;
root
未初始化,因此行为未定义。
估计是在这里实例化avl对象的时候
avl a(0);
如下所示class的构造函数被调用。
avl(int data)
{
root->data = data;
root->parent = NULL;
root->left = NULL;
root->right = NULL;
}
但是在这里我看到根指针没有分配任何内存
下面的程序是一个 bst 树,它在未优化的设置下工作正常,但在特殊情况下会产生 SIGSEGV。由于我的调试技能没有扩展到汇编,所以我可以使用一些输入来确定导致此错误的原因。下面是完整的代码,因此可以重现。没有什么特别的,有一个节点结构来保存节点数据,一个简单的插入操作和一个确认树高度的方法。
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct avl_tree_node //node data
{
int data;
int balance{0};
avl_tree_node *left{NULL};
avl_tree_node *right{NULL};
avl_tree_node *parent{NULL};
}node;
class avl
{
private:
node *root;
int get_height(node *head) //calculates the height
{
if (head == NULL)
return -1;
int l_height = get_height(head->left);
int r_height = get_height(head->right);
if (l_height > r_height)
return l_height+1;
return r_height+1;
}
void unbalanced_insert(node *head, int item); //method definition for a simple insert
public:
avl(int data)
{
root->data = data;
root->parent = NULL;
root->left = NULL;
root->right = NULL;
}
int height() //gives the height
{
return get_height(root);
}
void unbalanced_insert(int item) //wrapper
{
unbalanced_insert(root, item);
}
};
void avl::unbalanced_insert(node *head, int item) //inserts node to the tree
{
//cout << "stepped" << endl;
if (item > head->data)
{
if (head->right == NULL)
{
head->right = (node*)malloc(sizeof(node));
head->right->data = item;
head->right->parent = head;
head->right->left = NULL;
head->right->right = NULL;
head->balance = 1;
return;
}
unbalanced_insert(head->right, item);
head->balance++;
return;
}
else
{
if (head->left == NULL)
{
head->left = (node*)malloc(sizeof(node));
head->left->data = item;
head->left->parent= head;
head->left->left = NULL;
head->left->right = NULL;
head->balance = -1;
return;
}
unbalanced_insert(head->left, item);
head->balance--;
return;
}
}
int main()
{
avl a(0);
for (int i = 1; i < 5; i++) //works until i < 4
{
a.unbalanced_insert(i);
}
cout << a.height() << endl;
return 0;
}
在正常情况下,我很高兴这适用于未优化的标志,但我必须使用特定的标志来构建它。其中之一是 -O2
标志。分段错误发生在 avl a(0)
对象构造和 main 中的 for 循环之间。该错误似乎还取决于 for 循环的布尔检查。如果 i < 4
并执行: g++ avl.cpp -g -O2 -o program && ./program
一个明显的问题,它发生在 main
中的第一个函数调用中,即 avl a(0)
:
root->data = data;
root
未初始化,因此行为未定义。
估计是在这里实例化avl对象的时候
avl a(0);
如下所示class的构造函数被调用。
avl(int data)
{
root->data = data;
root->parent = NULL;
root->left = NULL;
root->right = NULL;
}
但是在这里我看到根指针没有分配任何内存