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 循环内修改ASetBList?请发布更完整的列表。另请注意,使用BList.back() 是访问最后一个元素的更好方法。 提供一个完整的、可编译的示例来演示该问题。仅仅因为使用不同的设置问题似乎消失了,并不意味着编译器或库在其他设置中做错了什么。这可能意味着(很可能确实意味着)您的代码具有未定义的行为。 【参考方案1】:

在 C++03 或更早的版本中,临时对象的副本放在 CListCList 对象内的 BList 上。

复制C::BList成员时,会创建一个全新的list&lt;B&gt;,但是复制C::BListIter成员时,新的C::BListIter迭代器仍然引用原@987654329中的C::BList列表@object - 这是一个被破坏的临时对象。这样迭代器就会引用已销毁列表的元素。

在 C++11 中,使用移动构造函数而不是复制构造函数,因此生成的迭代器不会引用死对象。

【讨论】:

以上是关于C++98/C++03 STL 设置错误?的主要内容,如果未能解决你的问题,请参考以下文章

STL相关问题

STL algorithm算法max,max_elements(33)

错误的 STL 标头

为什么说99%的人,看到的世界都是错误的?

Xcode STL C++ Debug 编译错误

Visual Studio 2019 STL 包含错误