问题在下面以粗体显示:
这很好用:
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的建议并经历了以下循环
#if 0
#endif
收缩包装主程序。解决方案:删除协议缓冲区的链接可以解决问题
答案 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库是另一个平台,我不确定会出现什么行为。