2017-07-28 21 views
0

このコードを実行して、scanfの入力として "Hello"(3文字以上)を入力すると、配列strはオーバーフローしません。これは私には少し奇妙に聞こえますが、もちろん私は何かが欠けています。誰もがここで何が問題なのか分かっていますか?どうもありがとう!配列がオーバーフローしない(C言語)

char str[3]; 
scanf("%s", str); 
printf("%s\n", str); 
+2

あなたの配列の境界を上書きすることは[未定義の動作](https://stackoverflow.com/documentation/c/364/undefined-behavior/2144/accessing-memory-beyond-allocated-chunk)です。 「オーバーフローしない」というのは、「セグフォルトなしで印刷する」という意味で、今回はラッキーです。 "Hello"は 'str'に収まらないので、あふれてしまいます。あなたがすべてのことがうまくいっていると思うので、本当に_unlucky_です。 – yano

+1

実際には関係はありませんが、2つ以上の文字を入力するとubが呼び出されることに注意してください。この種のエラーをキャッチするために使用できるランタイムツールがいくつかありますが、警告フラグはこれをキャッチしませんが、初期化されていない変数を読み込もうとするなど、他のub呼び出しコードをキャッチするためには便利です。 – George

+0

それは私の心に来るすべての文字列を入力しようとしているので、実際には本当に奇妙で、エラーは表示されません。たぶんそれは自動的にそのすべてを処理する "最新の"コンパイラです。私はちょうどMac上のターミナルを使ってコンパイルし、 "gcc -o fs main.c"と入力して実行しています。 –

答えて

1

私はあなたのコードを実行しようとした、そしてそれはありませんセグメンテーション違反:

./main 
ofejnhofewnhouwnofwbeqofenoifwenofwenoubwuiowgebouwegfougewfnbnbboue 
ofejnhofewnhouwnofwbeqofenoifwenofwenoubwuiowgebouwegfougewfnbnbboue 
Segmentation fault (core dumped) 

私はあなたがscanf()に合格しようとしているどのように多くの文字を知らないが、あなたが知っている必要があり、時々コンパイラこと保存されたESP/EIPと初期変数の間にパディングを実行します。

特に、ここでは、スタックに3バイトのメモリ領域を作成しています。コンパイラは最初に4に丸めます(x64では8)。しかしそれでも、それはより多くのスペースを追加するかもしれません。 gdb

disass mainは私を与える:

0x000000000040057d <+0>: push %rbp 
    0x000000000040057e <+1>: mov %rsp,%rbp 
    0x0000000000400581 <+4>: sub $0x20,%rsp 

sub 0x20は32バイトで、明らかな方法より3バイトです。

厳密な "ダミー" Cのアセンブラディレクティブは期待しないでください。コンパイラは、意識しているよりも多くの最適化と意思決定を行います。

;-)

+1

入手しました。ありがとうございました :) –

1

Cランタイムは発行しません...あなたのバッファとEIP間のバイトの正確な範囲は、通常、ブルートフォースを実行するために必要ですが、巧妙なハッカーがより興味深いアプローチを見つけるかもしれない発見しようとすると、エラー/警告メッセージが表示されますが、誤った結果が表示されます。 オーバーフロー/アンダーフローをチェックするには、あなたの責任で行ってください。

2

あなたは "配列strはオーバーフローしません"と言ったが、どのように知っていますか?オーバーフローがどのように現れると思いますか?

実際、配列は、がオーバーフローしました。あなたはちょうど「幸運」を得て、(目に見える)反響はなかった。

コンピュータプログラミングについて理解するのは難しいことの1つは、ルールの適用がかなり矛盾している可能性があることです。交差点の信号が「歩いてはいけない」と言われても、車は来ないので、通りを横切ると、すぐに警官が現れておらず、あなたに尋ねると、あなたはどんなに驚いていますか?ジャイウォークのチケット?それは基本的にここで起こったことです。

関連する問題