0

ここに私は非常に単純なプログラムを持っています、そして出力は私にとって非常に奇妙です、

#include "stdio.h"
#include "string.h"

void func_stack();

int main(int argc, char *argv[]) {
    func_stack();
}

void func_stack() {
    int a = -1;
    char s[4];
    int b = -1;

    strcpy(s,"1234");
    printf("a+b result to %d\n",a+b);
}

strcpy 関数は、後の int 変数 "b" に対して '\0' オーバーライドを使用し、奇妙な計算結果を返すと思いますが、x86 Linux マシンでコンパイルした後も、結果として -2 が得られました。同じ結果です。 strcpy が発生しないためです。

なぜこれが起こるのか誰でも説明できますか?

4

5 に答える 5

3

C 文字列は NUL で終了します。を使用strcpy()して にコピー"1234"するとs、実際には NUL ターミネータを含めて5バイトがコピーされます。次に、配列の境界を超えて書き込みを行っているため、未定義の動作sが呼び出されています。

これを実行したときに実際に何が起こるかは、CPU アーキテクチャとコンパイラ (およびコンパイラ オプション、最適化など) によって異なります。

于 2012-05-09T04:23:20.153 に答える
2

配列サイズを + 1 に変更します

例: "you"配列のサイズは 3+1 >> char s[4];

したがって、コード "1234"の配列サイズは 4+1 >> char s[5]; です。

最後の 1 バイトはNULL、文字列の末尾として使用されます。

CMIIW

于 2012-05-09T04:29:21.983 に答える
0

グレッグが言ったように、あなたは未定義の振る舞いを呼び出しているので、何でも起こり得ます。作業しているマシンは64ビットですか?その場合、変数がワードアラインされている可能性があるためs、整数の前に4バイトのパディングが追加されます。

于 2012-05-09T04:30:58.660 に答える
0

a = b = -1を実行しているため、それらのすべてのビットは1である必要があります。デバッガーまたはprintfを使用して、s [4]の「\0」がどこに書き込まれているかを確認するには、のアドレスを確認します。

&s[4], 
((char*)&a) and ((char*)&a)+(sizeof(int)-1),
((char*)&b) and ((char*)&b)+(sizeof(int)-1)

aとbのアドレスがs[0].. s [4]と重複しない場合、結果は-2になります。

于 2012-05-09T04:33:51.340 に答える
0

あなたstrcpyは5文字をコピーしようとしています。つまり1234\0、4 文字の配列になります。そのため、スタック上の何かを上書きしているため、この動作を観察しています。

于 2012-05-09T04:30:19.700 に答える