为什么静态变量中的溢出会导致seg错误而不是全局变量?

时间:2015-04-08 04:02:48

标签: c gcc buffer-overflow

为什么代码会因第一组代码的分段错误而失败,但第二个代码块没有? (唯一不同的是,字符在第一个中是静态的,而在第二个中不是静态的。)

#include <string.h> 
#include <stdio.h>
static char a[16];
static char b[16];
static char c[32];
int main(int argc, char *argv[]) {
    strcpy(a, "0123456789abcdef");
    strcpy(b, "0123456789abcdef");
    strcpy(c, a);
    strcat(c, b); 
    printf("a = %s\n", a);
    return 0;
}

#include <string.h> 
#include <stdio.h>
char a[16];
char b[16];
char c[32];
int main(int argc, char *argv[]) {
    strcpy(a, "0123456789abcdef");
    strcpy(b, "0123456789abcdef");
    strcpy(c, a);
    strcat(c, b); 
    printf("a = %s\n", a);
    return 0;
}

起初我认为这是因为它们存储在哪里,但它们都在bss区域(全局和未初始化)。 根据我在Stackoverflow上理解和阅读的内容,所有静态功能都是将变量限制为内部链接而不是其他内容。

(我知道没有为空字符分配空间。这种行为是一致的。)

2 个答案:

答案 0 :(得分:3)

只是因为运气。无论何时,你越过数组的定义限制的边界(无论是静态的还是全局的,无论如何),在C中都没有数组边界检查,因此,你可能会或可能不会得到运行时违规,运气因素来自在。 您需要分配额外的空间,包括字符串null终结符:

char a[16+1];
char b[16+1];
char c[32+1];

答案 1 :(得分:2)

基本上,您在两个代码段中都有 数组越界访问 ,这将导致未定义的行为。因此,第一个代码段可能会在其他系统上崩溃。由于没有定义行为,可能会发生任何事情,在你的情况下,你很幸运,并没有看到崩溃(第一个代码片段),但你永远不能依赖它。