連想コンテナのend()要素が最後の要素と同じ値を出力するのはなぜですか?[複製]

Dec 10 2020

以下のコードでは、イテレーターが指す値は、最後の要素と最後から2番目の要素の両方で同じです。

#include <iostream>
#include <set>
using namespace std;


int main() 
{
    set<int> s1 = {4,3,2,5,1};
    set<int>::iterator i;
    
    i = s1.end();
    cout << *i << endl; // 5
    
    i--;
    cout << *i << endl; // 5
    
    
    cout << *s1.end() << endl;  // 5
    cout << *(--s1.end()) << endl;  // 5
    
    return 0;
}

私の理解では、end要素が指す値はnullである必要があります。なぜそうなのですか?

回答

6 TonyTannous Dec 10 2020 at 20:53

未定義の振る舞い、std :: set :: endを呼び出しました

セットの最後の要素に続く要素にイテレータを返します。この要素はプレースホルダーとして機能します。アクセスしようとすると、未定義の動作が発生します。


未定義の動作は、プログラム全体を無意味にします。

1 largest_prime_is_463035818 Dec 10 2020 at 20:55

私の理解では、end要素が指す値はnullである必要があります。なぜそうなのですか?

なぜあなたの理解が間違っているのか私にはわかりません;)。卑劣さはさておき:いいえ。「終了要素」はありません。end最後の要素過去1にイテレータポイント。逆参照することはできません。実行すると、未定義の動作が呼び出されます。

コンテナの最後の要素は通常「戻る」と呼ばれ、多くのコンテナにはback()それにアクセスするためのメソッドがあります。

AsteroidsWithWings Dec 10 2020 at 21:01

私の理解では、end要素が指す値はnullである必要があります。なぜそうなのですか?

そうではありません。

過去1回のイテレータは何も「指し示し」ません。参照解除できません。

C文字列は、最初はこのルールの例外のように見えるかもしれませんが、そうではありません。NULLチェックできる文字で論理的に終了しますが、NULLそれでもcharオブジェクトの配列の一部であり、逆参照することはできません。char*これが、その配列の過去1回の反復子です。C文字列のヌルターミネータを「このページは意図的に空白のままにした」と考えてください。このページにはこれ以上のストーリーはありませんが、それでもページです。

連想コンテナのend()要素が最後の要素と同じ値を出力するのはなぜですか?

これは、動作が定義されていないプログラムの1つの考えられる結果です。