【问题标题】:g++ -O2 flag giving segmentation faultg++ -O2 标志给出分段错误
【发布时间】:2020-04-16 06:12:35
【问题描述】:

下面的程序是一个 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 &lt; 4 并使用以下命令执行,则此操作正常:g++ avl.cpp -g -O2 -o program &amp;&amp; ./program

【问题讨论】:

    标签: c++ assembly optimization g++


    【解决方案1】:

    一个明显的问题,它发生在main的第一个函数调用上,即avl a(0)

    root-&gt;data = data;

    root 未初始化,因此行为未定义。

    【讨论】:

    • 我现在看到了我的业余错误。但是为什么它在未优化的标志下工作呢?
    • 未定义的行为。任何事情都可能发生,包括“工作”。
    • 解释一下
    • @SilverFlash:如果您想确切地知道为什么它会发生该错误,请在调试器中单步执行 asm 并查看 root-&gt;data 恰好指向的值。
    • 从技术上讲,它不起作用。它只是做了一些未定义的事情,这恰好是你所期望的;)。
    【解决方案2】:

    我猜这里实例化avl的对象的时候。

     avl a(0);
    

    如下所示的类的构造函数被调用。

    avl(int data)
      {
        root->data = data;
        root->parent = NULL;
        root->left = NULL;
        root->right = NULL;
      }
    

    但是在这里我看到根指针没有分配任何内存

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多