2009-05-26 15 views
2

私は、これはsprintfのを使用する一般的な方法であると仮定します。C++ charポインタよりも多くの文字をsprintfで印刷するとどうなりますか?

char pText[x]; 
sprintf(pText, "helloworld %d", Count); 

が、正確に何が起こるか、char型のポインタが少ないメモリは、それがに印刷されるよりも、割り当てられている場合はどうなりますか?

つまり、xがsprintfの2番目のパラメータの長さよりも小さい場合はどうなりますか?

私はsprintfステートメントに続くコードでいくつか変わった動作をするので、私は尋ねています。

+0

sprintfのこの使用法は一般的ですが、非常に間違っています:) –

+0

メモリ内の次のものが書き込まれます。これはスタックまたはその他の変数です。 – pjc50

答えて

10

一般的に「正確に」何が起こるかは答えられません。これを実行するとUndefined behaviorが呼び出されます。これは基本的に何かが起こる可能性があることを意味します。

それは単にそのようなケースを避けるため、どこで利用できる安全な機能を使用することをお勧めします:

char pText[12]; 
snprintf(pText, sizeof pText, "helloworld %d", count); 

snprintf()がバッファサイズで追加の引数を取り、そこにある以上のことを書きませんか用のお部屋。

+0

ありがとう、MSVCにもこのようなものがありますか? – clamp

+1

はい、sprintf、strcatなどの安全でない機能を使用すると、新しいMSVCが警告を出します。 –

+0

はい、_snprintfがありますが、正確には同じではありません。詳しくはhttp://www.di-mgtをご覧ください。 com.au/cprog.html#snprintf – schnaader

0

Buffer Overflowをスペルできますか?可能な結果の1つはスタックの破損で、スタックベースの脆弱性に対して脆弱になります。

+2

これはスタックオーバーフローではありませんが、バッファオーバーフロー - -1 –

+0

errです。あなたは "バッファオーバーフロー"を意味します –

+0

Ooops、thanks - バッファオーバーフロー。 – gimel

6

これは一般的なエラーで、char配列を上書きした後でメモリにつながります。したがって、たとえば、文字配列の後にメモリ内にいくつかのintまたは別の配列があり、それらがテキストで上書きされる可能性があります。

問題全体に関する詳細な説明(バッファオーバーフロー)hereを参照してください。いくつかのアーキテクチャでは、最大長(あなたの場合はx)を定義する4番目のパラメータを持つsnprintfルーチンを提供するというコメントもあります。もしあなたのコンパイラがそれを知らないならば、それをあなた自身で書いて、そのようなエラーを得ることができないようにすることができます。

このようなエラーが発生した後の動作は定義されておらず、非常に奇妙なエラーが発生する可能性があることに注意してください。変数は通常、4で割り切れるメモリ位置に配置されるので、1バイトまたは2バイトをあまり書き込んでいない(つまり、NULを忘れるなど)ほとんどの場合、エラーに気付かないことがありますが、ケース。これらのエラーは、他の変数が変更され、コードのまったく異なる部分でエラーが頻繁に発生するため、デバッグが困難です。

2

この状況での動作は未定義です。通常、あなたはクラッシュしますが、無関係な変数やそのようなものには奇妙な値が現れることはありません。あなたのコードは間違った機能を呼び出すかもしれませんし、あなたのハードドライブをフォーマットし、実行中の他のプログラムを殺すかもしれません。これは、バッファに多くのメモリを割り当てることでこれを解決するのが最善です。

+1

«あなたのバッファにもっと多くのメモリを割り当てる» - HUH? -1 –

+0

"もっと"ではなく "十分な"と言っているはずです –

+0

@Anton:例えば、32ビットマシンの%dは11文字以上を必要としませんしたがって、この例ではサイズを動的に計算する必要はありません。しかし、ほとんどのC++プログラマは、このような低レベルのエラーを作成する機会を逃したいと考えています。 –

3

これは、バッファオーバーランと呼ばれます。

sprintfは、アドレスに応じてpTextに続くメモリを上書きします。 pTextがスタック上にあるので、sprintfはローカル変数、関数の引数、戻りアドレスを上書きして、あらゆる種類のバグにつながる可能性があります。この種のコードの結果、多くのセキュリティ上の脆弱性が生じます。攻撃者はバッファオーバーランを使用して、自分のコードを指す新しいリターンアドレスを書き込みます。

1

私はこれを何回もやりましたが、メモリ破損エラーが表示されます。私の知る限り、私は私がこのようにいくつかのことを行っている覚えている: - は

vector<char> vecMyObj(10); 
vecMyObj.resize(10); 
sprintf(&vecMyObj[0],"helloworld %d", count); 

しかし、ベクトルのデストラクタが呼び出されたときのサイズは10、その後小さければ、私のプログラムは、メモリ破損エラーが発生し、それが正常に動作します。

関連する問題