【问题标题】:How does set::erase() behave for set::end as its argument?set::erase() 对于 set::end 作为其参数有何表现?
【发布时间】:2013-03-11 19:53:40
【问题描述】:

假设我们有这段代码:

set<int> s;
set<int>::iterator it = s.find(val);
s.erase(it);

正如cplusplus.com所说,如果set&lt;int&gt; s中不存在int val,那么s.find(val)将返回set::end

现在我的问题是,如果我们将set::end 传递给set::erase(),会发生什么?

是否可以接收segmentation faultaborted 等信号并得到运行时错误?或者这个特殊情况是在set处理的?

【问题讨论】:

  • 我相信它是未定义的,你不知道会发生什么,即使在同一程序运行期间它也可以做不同的事情。
  • 为什么不让您的代码更简单,只使用:s.erase(val);(即使val 不存在,它也会给出定义的行为)?
  • “如果指定了无效的位置或范围,则会导致未定义的行为。” Last line
  • 谢谢! (我问这个问题是因为我在比赛中做过这种愚蠢的方法,我没有时间测试它。现在我只记得不要使用这种方法,因为它的行为是未定义的)

标签: c++ stl segmentation-fault set


【解决方案1】:

在 C++03 中,采用单个迭代器的 std::set::erase() 的行为在表 69 中定义,其中具有以下假设(添加了突出显示):

在表69中,X是关联容器类,a是X的值,a_uniq是X支持唯一键时的X值,a_eq是X支持多键时的X值,i和j满足输入迭代器要求并引用 value_type 的元素,[i, j) 是有效范围,p 是 a 的有效迭代器,q 是 a 的有效可解引用迭代器,[q1, q2) 是a 中的有效范围,t 是 X::value_type 的值,k 是 X::key_type 的值,c 是 X::key_compare 类型的值。

表 69 说明了 erase() 函数:

a.erase(q) - 删除q指向的元素

换句话说,迭代器必须是可解引用的。如果不是,则它是未定义的行为,因为未满足前提条件。

对于图书馆的行为方式没有任何承诺。某些库(例如 MSVC)可以在某些配置中包含迭代器调试。例如,在带有调试配置的 VS 2012 中运行时,您将看到以下内容:

---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!

Program: C:\Windows\system32\MSVCP110D.dll
File: c:\program files (x86)\microsoft visual studio 11.0\vc\include\xtree
Line: 1326

Expression: map/set erase iterator outside range

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)

---------------------------
Abort   Retry   Ignore   
---------------------------

【讨论】:

    【解决方案2】:

    这是未定义的行为。 IE。它可能什么也不做,使程序崩溃等。不要这样做,即使你的 stdlib 实现“工作正常”。

    【讨论】:

    【解决方案3】:

    对于关联容器,erase 定义如下:

    a.erase(q)
    返回类型:iterator
    擦除q 指向的元素。返回一个迭代器,该迭代器指向紧跟在q 之后的元素,在该元素被擦除之前。如果不存在这样的元素,则返回a.end()

    此函数仅根据q 定义。 q 被描述为“一个有效的可取消引用 const iterator to a"。过去的迭代器是不可取消引用的,所以你会得到未定义的行为。

    是否有可能接收到分段错误或中止等信号并得到运行时错误?

    是的,这是可能的,但你根本无法保证会发生什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-20
      • 2014-08-07
      • 1970-01-01
      • 1970-01-01
      • 2011-07-26
      • 2012-09-14
      • 1970-01-01
      相关资源
      最近更新 更多