ベクターコードがアサートしているのはなぜですか?とにかくアサートとは何ですか?
-
03-07-2019 - |
質問
<!> quot; assert <!> quot;とは、具体的には、エラーを取り除くにはどうすればよいですか。データメンバーint xを持つクラスへのポインターのベクトルを作成し、これを実行する場合:
for(I=antiviral_data.begin();I<antiviral_data.end();I++)
{
if((*I)->x>maxx)
{
antiviral_data.erase(I);
}
}
プログラムを実行すると、xがmaxxより大きくなるまでエラーが発生せず、.erase()を使用します。この時点でこのエラーが発生します。
デバッグアサーションが失敗しました!
プログラム:... My Documents \ O.exeファイル: ... include \ vector行:116
式: (<!> quot; this-<!> gt; _Has_container()<!> quot;、0)
プログラムの詳細については アサーションの失敗を引き起こす可能性があります Visual C ++ドキュメント アサートします。
(再試行を押してアプリケーションをデバッグします)
[中止] [再試行] [無視]
また、coutを使用しようとした場合:
cout<<(*antiviral_data.begin())->x<<endl;
このエラーが表示されます:
デバッグアサーションが失敗しました!
プログラム:... My Documents \ O.exeファイル: ... include \ vector行:98
式:ベクトル反復子ではありません 退治可能
プログラムの詳細については アサーションの失敗を引き起こす可能性があります Visual C ++ドキュメント アサートします。
(再試行を押してアプリケーションをデバッグします)
[中止] [再試行] [無視]
ベクターのデータを使用できない理由と修正方法を教えてください。
ALSO:antiviral_dataは単一の要素を持つポインターのベクトルです:
antiviral_data.push_back(new aX1(player.x,player.y,'>'));
それが役立つ場合。
解決
アサーションを取得する最も可能性の高い理由は、消去後にIをインクリメントすることです。代わりにこれを試してください:
for(I=antiviral_data.begin();I!=antiviral_data.end();)
{
if((*I)->x>maxx) I=antiviral_data.erase(I); else ++I;
}
http://www.cppreference.com/wiki/stl/vector/も参照してください。消去、そのページで無効なイテレータを検索します。
他のヒント
アサートは通常、デバッグおよびエラー制御のために開発者が入力した式です。異なる<!> quot;健全性チェック<!> quot;コード内で、チェックに達していない場合にプログラムをクラッシュさせます。
たとえば、道のどこかで2つの数値を分割するコードがあるとします。常にゼロ以外の除算が必要ですが、引数が誤って計算された場合に備えて、除算の前にアサートを設定します。アサートが失敗した場合、道路のどこかでエラーが発生したことを意味します。
アサーションは通常、コードのデバッグバージョンにのみ表示されます(ビジュアルC ++を使用する場合は、デバッグおよびリリース用にコンパイルできます)。リリースモードでコンパイルすると結果が削除されますが、エラーが発生し、おそらく本当に悪い結果になる可能性があるため、非常に悪い考えです。
Vectorの実装のどこか(標準ですか)、特に98行目にはアサートがあります。ベクトルコードにアクセスできる場合は、アサートが何であるかを確認するか、その時点までデバッグします。これは、ベクターの実装またはベクターを呼び出すコードのエラーを示している可能性があります。
投稿した内容から、何が起こっているかのヒントが得られますが、ベクトルが定義されている場所など、プログラムをさらに貼り付けることができれば便利です。
問題は消去呼び出しにあります。コンテナを反復処理すると同時に、そこから要素を消去しています。消去を行った後、イテレーターは無効になります。ベクターから特定の値の要素を削除する場合は、remove_ifアルゴリズムを使用してeraseを使用します。これは消去-削除イディオムとして知られており、スコット・マイヤーの効果的なSTLの本で非常によく説明されています。詳細については、ベクターから要素を消去するこの質問も参照できます。 p>
アサーションとは何か、それがコードでトリガーされている理由については、すでにいくつかの良い回答があります。ここで、2パス消去にSTLアルゴリズムを使用することを検討できます。
namespace {
struct exceeds : public std::unary_function< TheUnknownType*, bool >
{
exceeds_max( int max ) : maxx( max ) {}
bool operator()( TheUnknownType* data ) {
return data->x < max;
}
private:
int maxx;
};
}
void your_function()
{
std::vector< TheUnknownType* >::iterator new_end;
new_end = std::remove_if( antiviral_data.begin(), antiviral_data.end(), exceeds(maxx) );
antiviral_data.remove( new_end, antiviral_data.end() );
}
主な利点は、ベクトル内の要素の消去が高価な操作であることです。消去された各要素について、その位置からベクトルの終わりまでのすべての要素を最初の位置に移動する必要があります。消去する2番目の要素は、そこからすべての要素の2番目の移動を強制します... em>削除されていない最後の要素。次に、要素を再配置する必要のないstd :: vector <!> lt; <!> gt; :: removeを1つ実行できます。