简体   繁体   English

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

[英]Static global variables vs global variables C

I have the program below. 我有下面的程序。 If i declare variables a,b,c static global variables, it gives segmentation fault, but if i declare them non-static global or as local variables, it won't give segmentation fault. 如果我将变量a,b,c声明为静态全局变量,则会出现分段错误,但是如果我将其声明为非静态全局变量或作为局部变量,则不会出现分段错误。 Why does it behave in such a way? 为什么会这样表现? I know that there is more data than variables can store, but why does it give seg fault when only its declared static? 我知道数据存储的量超过了变量,但是为什么仅声明为静态时它会产生段错误? Are statically declared variables stored in some different part of the the stack frame where overwriting is not allowed? 是否将静态声明的变量存储在堆栈框架的某些不允许覆盖的不同部分中?

EDIT: I know strcpy is not safe. 编辑:我知道strcpy是不安全的。 But that is not my problem. 但这不是我的问题。 I want to understand why one overflow gives segfault, why the other overflow might not give 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;
}

Careful that const char* string in C are always 0-terminated, meaning that the string "0123456789abcdef" is actually 17 characters: "0123456789abcdef\\0" 请注意,C中的const char *字符串始终以0结尾,这意味着字符串“ 0123456789abcdef”实际上是17个字符: "0123456789abcdef\\0"

I suggest you to use always the secure version 我建议您始终使用安全版本

strncpy() 

You can also have a look at the documentation which tells you explicitly that the null character is included. 您还可以查看文档,该文档明确告诉您包含空字符。

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

memory alignment matters in stack variable. 内存对齐在堆栈变量中很重要。 Try it with -fstack-protector-strong or similar stack protection option you will see the crash. 尝试使用-fstack-protector-strong或类似的堆栈保护选项,您将看到崩溃。 Also declare an int after c and overflow your array c, you can see the crash. 同样在c之后声明一个int并溢出数组c,您可以看到崩溃。 you need to make sure that there is no padding. 您需要确保没有填充。 since b is an array, whatever you overflow from 'a' goes to b. 因为b是一个数组,所以从'a'溢出的所有内容都会进入b。 Try something like: 尝试类似:

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

you will see the crash when you overflow c. 当您溢出c时,您将看到崩溃。

You are hitting undefined behaviour when you overflow. 当您溢出时,您将遇到未定义的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM