うstd::vectorのオペレーター[]コンパイルとの境界確認にはデバッグが発売
-
18-09-2019 - |
質問
を使用していVisual Studio2008年.
う意識がstd::vectorは、境界確認、()関数が未定義の行動しようとした場合にアクセスに何かをオペレーター[]誤して用いられています。
私の場合でコンパイルマプログラムの範囲チェックしている。そうすることによって、オペレーター[]が使用する時()関数を投げるように、std::out_of_rangeいもの。
リモードを作成しない境界のチェックオペレーターの[]での性能劣化が発生しません。-
私について考えこんで移動し、アプリの制作をBorland C++をVisual Studioおよび一部のコードしています(i=0のj=1):
v[i][j]; //v is a std::vector<std::vector<int> >
サイズのベクトルv[0][1](い要素が0のベクターは単一の要素).これが未定義の動作るのは、私がBorlandは0、VSでのぶ.私のようにクラッシュより返0なので、取得できます。'クラッシュには、std::out_of_range例外がスローされ、移動が完了するより速く(そして同社は中国で最も積極的になりのバグがBorland隠れた).
解決
Visual Studio2005と2008てい境界-チェック operator[]
デフォルトでは、 両 デバッグおよびリリース構造を作成する環境が整いました
マクロの制御にこの動作は _SECURE_SCL
.設定で0を無効にする境界-チェックしている。
現在の計画、VS2010は無効での範囲チェックによりデフォルトでリリース構築、さま、ありがとうございましたのでデバッグ.のマクロはもっと改称 _ITERATOR_DEBUG_LEVEL
.わからない場合があり正式な書類をご用意してわかりやすく展示するなど、先 こちらの や こちらの)
他のヒント
、STLコンテナの上境界チェックを行うにはフラグ_GLIBCXX_DEBUGを有効にします。 http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html の
私はあまりにも時期尚早これを尋ねたが、私はいくつかの知識を共有していますので、私はとにかく答えを掲示しています。
のVisual Studioで実装STLは既にデバッグモードでコンパイルするときに境界チェックを行います。これは<vector>
ヘッダで見ることができます:
reference operator[](size_type _Pos)
{ // subscript mutable sequence
#if _HAS_ITERATOR_DEBUGGING
if (size() <= _Pos)
{
_DEBUG_ERROR("vector subscript out of range");
_SCL_SECURE_OUT_OF_RANGE;
}
#endif /* _HAS_ITERATOR_DEBUGGING */
_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
return (*(_Myfirst + _Pos));
}
ので、ベクトルクラスの境界チェックがあります。私は他のコンテナを見ていなかったが、私は、彼らが同じメカニズムを持っていることを確信しています。
私は今、任意のWindowsマシンにアクセスすることはできません。しかし、私は/usr/include/c++/4.0.0/bits/stl_vector.hから、どこでもMy Mac OS Xのマシン上のG ++に付属するSTLの実装に見れば:
// element access
/**
* @brief Subscript access to the data contained in the %vector.
* @param n The index of the element for which data should be
* accessed.
* @return Read/write reference to data.
*
* This operator allows for easy, array-style, data access.
* Note that data access with this operator is unchecked and
* out_of_range lookups are not defined. (For checked lookups
* see at().)
*/
reference
operator[](size_type __n)
{ return *(begin() + __n); }
はチェックは、デバッグモードでも、イベントを行っていません。いいえ_GLIBCXX_DEBUGのmarcroは、このコードでは、ここでチェックアウトされません。
MSVCで配信独自のSTLの実装で見てくださいと行われているものを参照してください。何もチェックがどのような場合にpeformedされていない場合...あなたは選択の余地はないが、(で使用).. :-(
C ++は、速度のために例外をスローしないように[]ベクトル演算子を定義します。
あなたが主要な「隠れた」バグがなくなっという確信を得るまで、私はしばらくの間、デバッグの設定でアプリケーションをテストするためにあなたをお勧めする。