什么可能导致初始化顺序破坏堆栈?

时间:2012-02-01 15:38:17

标签: 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. 收缩包装代码到我在这里展示的,编译和测试,没问题。
  2. #if 0 #endif收缩包装主程序。
  3. 删除标题,直到它以收缩包装的形式编译。
  4. 删除库链接,直到以收缩包装形式编译。
  5. 解决方案:删除协议缓冲区的链接可以解决问题

4 个答案:

答案 0 :(得分:4)

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

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

所以,要么你没有讲完整个故事,要么你的STL实施已经破裂。

OR:您的代码中有未定义的行为。 C ++标准提供了无保证关于具有导致UB的构造的程序的行为,甚至在到达该构造之前。

答案 1 :(得分:3)

当其中一个创建的对象超出时,通常会出现这种情况 它在构造函数中的结束。这是最常见的原因 我在代码中看到的是,目标文件已经编译成不同的 标题的版本;例如在某个时间点,你添加(或 删除了其中一个类的数据成员,并没有重新编译所有类 使用它的文件。

答案 2 :(得分:1)

可能导致您看到的那类问题是用户定义的类型,其中包含行为不当的构造函数;

class BrokenType {
  public:
  int i;
  BrokenType() { this[1].i = 9999; } // Bug!
};

void process_batch( 
  string_vector & v
) 
{

  training_entry te;
  BrokenType b;  // bug in BrokenType shows up as assert fail in std::vector
  entry_vector sv; 
  assert(sv.size() < 100);
...
}

答案 3 :(得分:1)

您是否拥有适合您平台的Boost库的正确版本? (64位/ 32位)?我问,因为entry_vector对象似乎有几个boost :: uint32_t类型的成员变量。如果您的可执行文件是为一个平台构建的,并且加载的boost库是另一个平台,我不确定会出现什么行为。