0

次のコードがあるとします。

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

cplusplus.com が言ったように、 then にint val存在しない場合は、が返されます。set<int> ss.find(val)set::end

set::endここで私の質問は、set::erase()?に渡すとどうなるかということです。

segmentation faultまたはなどのシグナルを受信しabortedて​​実行時エラーを取得することは可能ですか? または、この特別なケースは で処理されましたsetか?

4

3 に答える 3

4

これは未定義の動作です。つまり、何もしない、プログラムがクラッシュするなどの可能性があります。stdlibの実装が「正常に機能する」場合でも、これを行わないでください。

于 2013-03-11T19:57:28.090 に答える
4

C++03 では、std::set::erase()1 つのイテレータを取る の動作が表 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   
---------------------------
于 2013-03-11T20:00:16.267 に答える
2

連想コンテナの場合、eraseは次のように定義されます。

a.erase(q)
戻り値の型:iterator
が指す要素を消去しqます。q要素が消去される直前の要素を指す反復子を返します。そのような要素が存在しない場合は、 を返しますa.end()

この関数は、 に関してのみ定義されqます。qは、「への有効な逆参照可能な const イテレータ」として記述されていますa。末尾イテレータは逆参照できないため、未定義の動作が発生します。

セグメンテーション違反や中断などのシグナルを受信して​​実行時エラーを取得することは可能ですか?

はい、可能ですが、何が起こるかについての保証はまったくありません.

于 2013-03-11T19:58:43.950 に答える