我有以下程序。如果我声明变量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;
}
答案 0 :(得分:1)
注意C中的const char *字符串总是以0结尾,这意味着字符串&#34; 0123456789abcdef&#34;实际上是17个字符:"0123456789abcdef\0"
我建议您始终使用安全版
strncpy()
您还可以查看明确告诉您包含空字符的文档。
答案 1 :(得分:0)
内存对齐在堆栈变量中很重要。 尝试使用-fstack-protector-strong或类似的堆栈保护选项,您将看到崩溃。 在c之后声明一个int并溢出你的数组c,你可以看到崩溃。 你需要确保没有填充。 因为b是一个数组,所以无论你从'a'溢出什么都会转到b。 尝试类似:
struct foo {
char c[10];
int x;
} __attribute__((packed));
当你溢出c时,你会看到崩溃。
当你溢出时,你正在达到未定义的行为。