0
char *asd = new char[5];
asd[10] = 'f';

このコードでデバッグを実行してもエラーが発生しないのはなぜですか? リリース ビルド中にクラッシュが発生します。

4

4 に答える 4

5

未定義の動作は、クラッシュする必要があるという意味ではないためです。

これは、正常に動作しているように見えることを含め、あらゆることが起こり得ることを意味します。

于 2012-05-11T11:32:04.120 に答える
1

通常の配列の代わりに std::vector を使用できます。これは、C++ または C の配列には境界チェックがなく、設計によるものであるためです (ただし、at メソッドを使用する必要があります)。配列は最初のメモリ アドレスへの単なるポンターであり、これを使用して反復できますが、境界に関する実行時情報はありません。良い例は文字列です。この理由から \0 ターミネータを使用しています。

デバッグについて: ac プログラムをデバッガーで実行する場合、このプログラムを運用システム上でのみ実行するのと 100% 等しくはありません。スレッドは良い例です。たとえば、gdb を実行すると違いがあります。

おそらく別のマシンまたは運用システムでは、クラッシュすることはありません。これを回避するには、たとえば valgrind を使用してコードを監視できます。

于 2012-05-11T11:35:11.637 に答える
0

asd[10] は単に「asd のアドレス + sizeof(10 バイト)」を意味します。asd に割り当てられているメモリ位置によっては、このメモリ アドレスをプログラムで使用できない場合があり、未定義の動作につながります。

  • 他の変数が asd[10] を上書きしないという保証はありません
  • アプリケーションのクラッシュ
于 2012-05-11T11:53:56.730 に答える
0

通常、コンパイルしてデバッグ中に実行すると、割り当てられたメモリ領域の周りにいくつかのガード ブロックが実装されます。高度なコンパイラは、上書きされたかどうかをチェックして、メモリ アクセス エラーを通知します。リリース中は、このようなものは何もありません。コンパイラがバイトを配置する場所に応じて、後の内容を上書きするだけで、それがすべてになる可能性があります。興味深い読み物は次のとおりです

于 2012-05-11T11:57:57.030 に答える