(これをVirtualBox Ubuntuで実行しています)それで私の質問は次のとおりです:なぜその8バイト配列に11文字を入力できるのですか?
ゼロ終了の場合は11+1=12文字。get()がarr[8]に13文字を書き込むとIOWクラッシュが発生します。
正確なスタックトレースを投稿していませんが、私の経験から、foo()が戻った後にクラッシュするはずです。
スタックフレーム(void foo()+ Gets()の場合)は(*)のようになります:
- <下位メモリアドレス>
- get()ローカル変数
- get()呼び出しの時点で保存されたスタックポインタ(いわゆる「プロローグ」)
- 差出人住所、foo()を指す
- foo()ローカル変数(あなたのchar arr [8])
- get()呼び出しの時点で保存されたスタックポインタ
- 差出人アドレス、foo()の呼び出し元を指します
- <上位メモリアドレス>
すべての情報から、最も重要なビットはリターンアドレスと保存されたスタックポインタです。また、あなたの場合の13バイト目の書き込みは、foo()関数の保存されたスタックポインタを破損している可能性があります。スタックポインタはまだ有効であるため、次のprintf()の呼び出しは成功する可能性が高いです(gets()から戻ることによって最後に変更されます)。ただし、foo()から戻ると、foo()の保存されたスタックポインタ(現在は破損)が復元され、呼び出し元の関数内からスタックにアクセスするアクションはすべて不正なアドレスに移動します。
私の経験から、これは最も可能性の高いシナリオです。スタックが破損していると、何が起こるかを確実に判断するのは非常に困難です。
(*)スタックフレームの構築方法の正確な詳細については、アーキテクチャのABI(アプリケーションバイナリインターフェイス)を探してください。たとえば、Inteli386の場合はIA-32ABI、AMD64の場合はAMD64ABIです。