配列の代わりに単一の文字を割り当てています。使用する:
char* ptr;
ptr=new char[65];
strcpy(ptr,"asdf");
delete[] ptr;
現在のように、最初a
は割り当てられたcharに書き込み、残りは割り当てられなかった任意のメモリに書き込みます。ランタイムは(デバッグビルドで)それを検出し、文句を言います。
私の答えの質問部分に私のコメントをする:
C ++には、質問のコードの潜在的なエラーを識別するメカニズムがありません。コンパイラが渡されるバッファのサイズを知る唯一の方法は、strcpy
静的分析を使用することであり、それが機能する場合と機能しない場合があります。しかし、たとえそうだとしても、コンパイラはのセマンティクスを知りませんstrcpy
。したがって、コンパイル時に、エラーについて警告することはできません。
現在、バッファがstrcpy
実行時に渡されるとき、そのバッファstrcpy
の大きさを知る方法はありません。したがって、呼び出し元が適切なバッファを提供したと想定し、コピーを続行します。運が良ければ、割り当てられたバッファをオーバーフローさせると、割り当てられていないページへの書き込みが原因ですぐにクラッシュします。そうしないと、メモリが破損します。
発生するエラーは、デバッグビルドで使用されるメカニズムの結果です。メモリマネージャーは、要求したバイトよりも数バイト多く割り当て、それらに特別なパターンを書き込みます。次に、割り当てられたメモリが解放されると、そのパターンがまだ存在するかどうかを確認します。そうでない場合は、ユーザーのコードが書き込まれていると文句を言います。リリースビルドでは、これらの追加のチェックはありません。そのようなバグは、気付かれることなく破損を引き起こす可能性があります。
このような場合を回避する唯一の方法は、より安全なコードを作成することです。
- のような高レベルの構造を使用します
std::string
。それらはあなたのためにメモリ管理を行い、低レベルの文字列関数を扱う必要からあなたを救います。
- Microsoftの(非標準の)安全なバリアント(たとえば、strcpy_s )を使用します。これらの関数はバッファのサイズも取得し、それが不十分な場合は失敗します-損傷を与えることはありません。
- (標準の)strncpyを使用し、最後の引数としてバッファーのサイズを渡し、戻り値をチェックして、コピーされた文字数を確認します。前の提案と同様に、間違ったバッファサイズを指定すると、損傷が発生します。
- 自分のつま先を撃ちたい場合は、C++が喜んで下向きの銃を手渡すことを覚えておいてください。生のバッファ、ポインタ、および低レベルの文字列関数の処理は注意して行う必要があります。言語はあなた自身の過ちからあなたを救うことはありません。