2

私のセットアップでこれを実行します:

  vector<int> myvector;
  for (int i=1; i<=5; i++) myvector.insert(myvector.end(),i);

  vector<int>::iterator it;
  for ( it=myvector.begin() ; it < myvector.end()+2; it++ )
    cout << " " << *it;

収量:

1 2 3 4 5 0 0

範囲外のイテレータを逆参照しようとすると、セグメンテーション違反が発生すると思いました。しかし、ベクターに含まれているタイプの空またはデフォルトで初期化されたオブジェクトを生成するようです。

これは明確に定義された動作ですか?そして、このプロパティはどこから、イテレータから、またはベクトルから来ますか?イテレータは、ある意味で範囲外の例外をキャッチし、代わりに空のオブジェクトを返しますか?

これをC++11リファレンスで見つけてみましたが、少し頭がおかしいようです。

4

3 に答える 3

6

これは未定義の動作です。つまり、セグメンテーション違反、経験したこと、またはその他のことを含め、何かが発生する可能性があります。基本的に、クラッシュしなかったのは幸運でした(または、観点からすると不運でした)。

于 2012-11-23T10:34:21.367 に答える
3

範囲外のイテレータを逆参照しようとすると、セグメンテーション違反が発生すると思いました。

いいえ、未定義の動作をします。この言語では、実行時チェックが必要になるため、イテレータアクセスをチェックする必要はありません。C ++は通常、不必要な実行時のオーバーヘッドを回避しようとし、プログラマーに必要なチェックを実行させます。

最新のプラットフォームのほとんどはページングされた仮想メモリを使用しており、数キロバイトの粒度でメモリ保護を提供します。これは、割り当てられたブロック(によって管理されるブロックなど)の後にアクセス可能なメモリが存在することが多いことを意味しますstd::vector。この場合、範囲外のアクセスは単にそのメモリを踏みにじります。

C++ライブラリでランタイムイテレータチェックを有効にできる場合があります。あるいは、 valgrindefenceなどのツールは、範囲外のアクセスを含むさまざまなメモリエラーのデバッグに役立ちます。

于 2012-11-23T10:50:22.660 に答える
0

C ++ベクトルの実装は配列を使用して行われます-サイズがを超えると、基になる配列のサイズが大きくなります:
Facebookがしばらく前にオープンソース化した興味深いコードがあります-メモリ管理に関するコメントは、何が起こるかを知るための優れた方法ですボンネットの下でFacebookFBvector

得られる結果は、「C配列」の範囲外アクセスと同等です-ランダム:-)

于 2012-11-23T10:46:38.727 に答える