静态全局变量与全局变量C

时间:2015-04-07 21:36:59

标签: c stack-overflow stackframe

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

编辑:我知道strcpy不安全。但这不是我的问题。我想了解为什么一个溢出会给出segfault,为什么另一个溢出可能不会给出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;
}

2 个答案:

答案 0 :(得分:1)

注意C中的const char *字符串总是以0结尾,这意味着字符串&#34; 0123456789abcdef&#34;实际上是17个字符:"0123456789abcdef\0"

我建议您始终使用安全版

strncpy() 

您还可以查看明确告诉您包含空字符的文档。

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

答案 1 :(得分:0)

内存对齐在堆栈变量中很重要。 尝试使用-fstack-protector-strong或类似的堆栈保护选项,您将看到崩溃。 在c之后声明一个int并溢出你的数组c,你可以看到崩溃。 你需要确保没有填充。 因为b是一个数组,所以无论你从'a'溢出什么都会转到b。 尝试类似:

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

当你溢出c时,你会看到崩溃。

当你溢出时,你正在达到未定义的行为。