c++ - 什么会导致初始化顺序损坏堆栈?

标签 c++ stack-corruption

问题在下面以粗体显示:

这很好用:

void process_batch( 
  string_vector & v
) 
{

  training_entry te;
  entry_vector sv; 
  assert(sv.size() == 0);
...
}

但是,这会导致断言失败:

   void process_batch( 
      string_vector & v
    ) 
    {
      entry_vector sv; 
      training_entry te;
      assert(sv.size() == 0);
      ...
   }

现在我知道这个问题不是收缩包装的,所以我将我的问题限制为:什么情况会导致这样的问题?具体来说:变量初始化损坏取决于堆栈帧中的出现顺序。我的代码中没有 malloc 或 free,也没有不安全的函数,如 strcpy、memcpy 等……它是现代 c++。使用的编译器:gcc 和 clang。

为简洁起见,这里是类型的

struct line_string
{
  boost::uint32_t line_no;
  std::string     line;
};

typedef  std::vector<boost::uint32_t> line_vector;
typedef std::vector<line_vector> entry_vector;
typedef std::vector<line_string> string_vector;

struct training_body
{
  boost::uint32_t url_id;
  bool relevant;
};

struct training_entry
{
  boost::uint32_t session_id;
  boost::uint32_t region_id;
  std::vector< training_body> urls;
};

p.s.,我绝不是说编译器有问题,这可能是我的代码问题。但是由于我正在模板化我很久以前写的一些代码,这个问题让我完全难住了,我不知道去哪里找问题。

编辑

听从了nim的建议,经历了下面的循环

  1. shrink wrap the code to what I have shown here, compile and test, no problem.
  2. #if 0 #endif 收缩包装主程序。
  3. 删除 header ,直到它以收缩包装形式编译。
  4. 删除库链接,直到以收缩包装形式编译。

解决方案:删除 Protocol Buffer 的链接可以解决问题

最佳答案

C++ 标准保证以下断言会成功:

std::vector<anything> Default; 
//in your case anything is line_vector and Default is sv
assert(Default.size() == 0);

因此,要么您没有讲述完整的故事,要么您的 STL 实现有问题。

或者:您的代码中有未定义的行为。 C++ 标准不保证具有导致 UB 构造的程序的行为,甚至在达到该构造之前。

关于c++ - 什么会导致初始化顺序损坏堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9098636/

相关文章:

C++ 堆栈和堆损坏

c++ - 堆栈变量已损坏

c++ - 函数声明的数组大小导致堆栈损坏,但干净的编译?

c++ - QT5 C++ 信号到 QML 槽不工作

c++ - 在 QFileDialog::getSaveFileName 中指定默认扩展名

c++ - 为 STL 兼容序列容器的实现命名一个好的指南)

c++ - 二进制搜索程序无法识别边界?

c++ - 将大 vector 存储在堆栈中是个坏主意吗?

c++ - 调试堆栈值损坏的好方法

c++ - C++ 中的自定义 list.sort 比较