2

私は以下のプログラムを持っています。変数 a、b、c の静的グローバル変数を宣言すると、セグメンテーション違反が発生しますが、非静的グローバル変数またはローカル変数として宣言すると、セグメンテーション違反は発生しません。なぜそのような振る舞いをするのでしょうか。変数よりも多くのデータを格納できることはわかっていますが、宣言された static のみの場合に seg fault が発生するのはなぜですか? 静的に宣言された変数は、上書きが許可されていないスタック フレームの別の部分に格納されていますか?

編集: strcpy が安全でないことはわかっています。しかし、それは私の問題ではありません。1 つのオーバーフローで segfault が発生する理由と、もう 1 つのオーバーフローで segfault が発生しない理由を理解したい。

#include<stdio.h>
#include<string.h>

static char a[16];
static char b[16];
static char c[32];

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

// char a[16];
 //char b[16];
 //char c[32];
    strcpy(a,"0123456789abcdef");
    strcpy(b,"0123456789abcdef");
    strcpy(c,a);
    strcpy(c,b);
    printf("a = %s\n",a);
    return 0;
}
4

2 に答える 2

1

C の const char* 文字列は常に 0 で終わることに注意してください。つまり、文字列 "0123456789abcdef" は実際には 17 文字です。"0123456789abcdef\0"

常に安全なバージョンを使用することをお勧めします

strncpy() 

また、ヌル文字が含まれていることを明示的に示しているドキュメントを参照することもできます。

http://www.cplusplus.com/reference/cstring/strcpy/

于 2015-04-07T21:42:08.333 に答える
0

スタック変数では、メモリの配置が重要です。-fstack-protector-strong または同様のスタック保護オプションで試してみると、クラッシュが発生します。また、c の後に int を宣言し、配列 c をオーバーフローさせると、クラッシュが発生します。パディングがないことを確認する必要があります。b は配列であるため、「a」からオーバーフローしたものはすべて b に移動します。次のようなものを試してください:

struct foo {
        char c[10];
        int x;
    } __attribute__((packed));

オーバーフローするとクラッシュが表示されます c.

オーバーフローすると、未定義の動作が発生します。

于 2015-04-07T21:49:26.157 に答える