1

问题在下面以粗体显示:

这工作正常:

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;
};

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

编辑

遵循 nim 的建议并经历了以下循环

  1. 将代码收缩包装到我在这里显示的内容,编译和测试,没问题。
  2. #if 0 #endif收缩包装主程序。
  3. 删除标题,直到它以收缩包装的形式编译。
  4. 删除库链接,直到以收缩包装形式编译。

解决方案:删除到协议缓冲区的链接可以解决问题

4

4 回答 4

4

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

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

所以,要么你没有讲述整个故事,要么你的 STL 实现有问题。

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

于 2012-02-01T15:45:15.967 回答
3

通常情况下,当创建的对象之一在构造函数中写入超出其末尾时。我见过的代码中发生这种情况的最常见原因是目标文件已使用不同版本的标头进行编译。例如,在某个时间点,您添加(或删除)其中一个类的数据成员,并且没有重新编译所有使用它的文件。

于 2012-02-01T15:50:30.127 回答
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);
...
}
于 2012-02-01T15:46:33.453 回答
1

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

于 2012-02-01T16:03:48.390 回答