2

我有下面的程序。如果我声明变量 a、b、c 静态全局变量,它会给出分段错误,但如果我将它们声明为非静态全局变量或局部变量,它不会给出分段错误。为什么它会以这种方式表现?我知道变量可以存储的数据多于变量可以存储的数据,但是为什么只有声明为静态时它会给出段错误?静态声明的变量是否存储在不允许覆盖的堆栈帧的某些不同部分?

编辑:我知道 strcpy 不安全。但这不是我的问题。我想了解为什么一个溢出会产生段错误,为什么另一个溢出可能不会产生段错误。

#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 回答