これは sprintf を使用する一般的な方法だと思います。
char pText[x];
sprintf(pText, "helloworld %d", Count );
しかし、char ポインタに割り当てられたメモリが印刷先よりも少ない場合、正確にはどうなりますか?
つまり、x が sprintf の 2 番目のパラメーターの長さよりも小さい場合はどうなるでしょうか。
sprintf ステートメントに続くコードで奇妙な動作が発生するため、質問しています。
一般的に、何が起こるかを「正確に」答えることはできません。これを行うと、いわゆる未定義動作が呼び出されます。これは、基本的に何かが発生する可能性があることを意味します。
このような場合を単純に回避し、可能な場合は安全な関数を使用することをお勧めします。
char pText[12];
snprintf(pText, sizeof pText, "helloworld %d", count);
snprintf()
バッファサイズである追加の引数をどのように取るか、および余裕がある以上に書き込みを行わないことに注意してください。
これは一般的なエラーであり、char配列が上書きされた後にメモリが発生します。したがって、たとえば、char配列の後にメモリ内にいくつかのintまたは別の配列があり、それらがテキストで上書きされる可能性があります。
ここで、問題全体(バッファオーバーフロー)に関する詳細な説明を参照してください。一部のアーキテクチャでは、最大長(この場合はx)を定義する4番目のパラメーターを持つsnprintfルーチンが提供されているというコメントもあります。コンパイラがそれを認識していない場合は、自分で記述して、そのようなエラーが発生しないようにすることもできます(または、常に十分なスペースが割り当てられていることを確認してください)。
このようなエラーの後の動作は未定義であり、非常に奇妙なエラーにつながる可能性があることに注意してください。変数は通常、4で割り切れるメモリ位置に配置されるため、1バイトまたは2バイトを書きすぎた場合(つまり、NULの場所を忘れた場合)、ほとんどの場合、エラーに気付かないことがありますが、他の場所では奇妙なエラーが発生します。ケース。これらのエラーは、他の変数が変更され、コードのまったく異なる部分でエラーが発生することが多いため、デバッグが困難です。
これは、バッファオーバーランと呼ばれます。
sprintf
pText
アドレスごとにたまたま続くメモリを上書きします。pText
はスタック上にあるため、sprintf
ローカル変数、関数の引数、および戻りアドレスを上書きして、あらゆる種類のバグを引き起こす可能性があります。多くのセキュリティの脆弱性は、この種のコードに起因します。たとえば、攻撃者はバッファオーバーランを使用して、自分のコードを指す新しいリターンアドレスを書き込みます。
この状況での動作は定義されていません。通常はクラッシュしますが、悪影響が見られない場合や、無関係な変数に奇妙な値が表示される場合などもあります。コードが間違った関数を呼び出したり、ハードドライブをフォーマットしたり、実行中の他のプログラムを強制終了したりする可能性もあります。バッファにより多くのメモリを割り当てることにより、これを解決するのが最善です。
私はこれを何度も行っていますが、メモリ破損エラーが発生します。私の知る限り、私はこのようなことをしたことを覚えています:-
vector<char> vecMyObj(10);
vecMyObj.resize(10);
sprintf(&vecMyObj[0],"helloworld %d", count);
しかし、ベクトルのデストラクタが呼び出されると、私のプログラムはメモリ破損エラーを受け取ります。サイズが 10 未満であれば、プログラムは正常に動作します。
バッファオーバーフローを綴ることができますか?考えられる結果の1つはスタックの破損であり、アプリがスタックベースの悪用に対して脆弱になります。