C++98/C++03 STL 设置错误?
Posted
技术标签:
【中文标题】C++98/C++03 STL 设置错误?【英文标题】:C++98/C++03 STL set bug? 【发布时间】:2014-02-05 23:40:08 【问题描述】:所有,
当我使用 set 时发生了一件奇怪的事情: 比方说:
struct A
int num;
bool operator<(const A& x) const
return num < x.num;
;
struct B
set<A> ASet;
;
struct C
list<B> BList;
list<B>::iterator BListIter;
C()
BList.push_back(B());
BListIter = --(BList.end());
;
我们可以在某个地方获得此代码:
list<C> CList;
CList.push_back(C());
list<C>::iterator CListIter = --(CList.end());
for (...)
A a = ...;
...
CListIter->BListIter->ASet.insert(a);
这将在几次迭代后导致分段错误。发生这种情况时,我发现在插入过程中引用并比较了一个无效项(它的地址是0x0000001b,所以肯定是错误的)。
有趣的是,当我打开 -std=c++0x 这个选项以使用 C++11 时,问题就消失了!所以不知道这是不是C++98/C++03设置的STL的bug?
谢谢,
凯文
【问题讨论】:
在您没有显示的代码中一定有更多内容。您是否在for
循环内修改ASet
或BList
?请发布更完整的列表。另请注意,使用BList.back()
是访问最后一个元素的更好方法。
提供一个完整的、可编译的示例来演示该问题。仅仅因为使用不同的设置问题似乎消失了,并不意味着编译器或库在其他设置中做错了什么。这可能意味着(很可能确实意味着)您的代码具有未定义的行为。
【参考方案1】:
在 C++03 或更早的版本中,临时对象的副本放在 CList
和 CList
对象内的 BList
上。
复制C::BList
成员时,会创建一个全新的list<B>
,但是复制C::BListIter
成员时,新的C::BListIter
迭代器仍然引用原@987654329中的C::BList
列表@object - 这是一个被破坏的临时对象。这样迭代器就会引用已销毁列表的元素。
在 C++11 中,使用移动构造函数而不是复制构造函数,因此生成的迭代器不会引用死对象。
【讨论】:
以上是关于C++98/C++03 STL 设置错误?的主要内容,如果未能解决你的问题,请参考以下文章