Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 指向全局静态变量的指针-不安全?_C - Fatal编程技术网

C 指向全局静态变量的指针-不安全?

C 指向全局静态变量的指针-不安全?,c,C,我有一个文件,其中有一个全局数组 static char name[6]; 和一个函数 static char* gen_name(char* dest, const size_t len) { for (int i = 0; i < len - 1; ++i) dest[i] = 'A' + (genrand_uint32() % ('Z' - 'A')); dest[len - 1] = '\0'; return dest; } 当另一个文

我有一个文件,其中有一个全局数组

static char name[6];
和一个函数

static char* gen_name(char* dest, const size_t len) {
    for (int i = 0; i < len - 1; ++i)
        dest[i] = 'A' +  (genrand_uint32() % ('Z' - 'A'));
    dest[len - 1] = '\0';
    return dest;
}
当另一个文件中的函数使用此指针时,它在Linux上运行良好,但当我在微控制器上运行相同的代码时,它会打印垃圾。 当我删除
static
关键字时,它工作正常

为什么会这样

我应该在什么时候使用
静态

我想我应该将所有未在文件外部使用的变量和函数声明为
静态
,这是否错误?

当您在标题中声明变量时,是否记得将其标记为
外部
?您需要这样做,否则会发生的情况是,您只需在包含头的每个文件中获得一个新变量。记住,
#include
只是一个复制粘贴作业;预处理器只是将头文件中的文本插入包含发生的位置。如果头文件中的文本是
char name[6]
,那么这就是您得到的;源文件中显示
char name[6]
的文本,导致变量
name
与其他源文件中的变量无关

如果将其标记为
extern
,则链接器会抱怨找不到该符号。这意味着
name
的定义不能是
static
,因为这会导致链接器无法找到它

因此,在头文件中,您需要以下声明:

extern char name[6];
在源文件中,您需要以下定义:

char name[6];

回答实际问题:是的,它非常安全。

当您在标题中声明变量时,是否记得将其标记为
extern
?您需要这样做,否则会发生的情况是,您只需在包含头的每个文件中获得一个新变量。记住,
#include
只是一个复制粘贴作业;预处理器只是将头文件中的文本插入包含发生的位置。如果头文件中的文本是
char name[6]
,那么这就是您得到的;源文件中显示
char name[6]
的文本,导致变量
name
与其他源文件中的变量无关

如果将其标记为
extern
,则链接器会抱怨找不到该符号。这意味着
name
的定义不能是
static
,因为这会导致链接器无法找到它

因此,在头文件中,您需要以下声明:

extern char name[6];
在源文件中,您需要以下定义:

char name[6];

回答实际问题:是的,它非常安全。

它原来是由另一个线程中的堆栈溢出引起的,将其标记为static会将其放在bss部分,就在溢出的堆栈后面。

它原来是由另一个线程中的堆栈溢出引起的,将其标记为static会将其放在bss部分,就在溢出的堆栈后面。

static关键字对函数和变量意味着不同的事情

函数默认为“extern”,即编译器公开其入口点,以便链接器可以找到它们,并且可以从任何编译模块调用它们。 如果将“static”放在函数声明的前面,则该函数将不再是公共函数,也就是说,它将只在同一源模块中被知道

“static”关键字用于变量(*)时具有非常不同的含义。这使它们无法改变。 当您说“staticcharname[6]”时,您是在告诉编译器您无意更改“name”的值

在PC上运行的Linux上,这并不意味着什么。您告诉编译器您不会更改该值,然后更改它。你撒谎了。没什么大不了的

一些微控制器有内部闪存,可以用来运行代码,并保持固定(恒定!)数据。 编译器和链接器使用您的承诺,即“name”不会更改,并将变量保留在闪存中。 你可以想象当你试图改变它时(没有)会发生什么

更准确地说,编译器将把所有静态变量放在类似.const的部分中,然后链接器将把该部分放在闪存中


(*)有一种看待“const”的方法,使得它在用于变量和函数时具有相同的含义。这里不重要。

静态关键字对函数和变量的含义不同

函数默认为“extern”,即编译器公开其入口点,以便链接器可以找到它们,并且可以从任何编译模块调用它们。 如果将“static”放在函数声明的前面,则该函数将不再是公共函数,也就是说,它将只在同一源模块中被知道

“static”关键字用于变量(*)时具有非常不同的含义。这使它们无法改变。 当您说“staticcharname[6]”时,您是在告诉编译器您无意更改“name”的值

在PC上运行的Linux上,这并不意味着什么。您告诉编译器您不会更改该值,然后更改它。你撒谎了。没什么大不了的

一些微控制器有内部闪存,可以用来运行代码,并保持固定(恒定!)数据。 编译器和链接器使用您的承诺,即“name”不会更改,并将变量保留在闪存中。 你可以想象当你试图改变它时(没有)会发生什么

更准确地说,编译器将把所有静态变量放在类似.const的部分中,然后链接器将把该部分放在闪存中


(*)有一种看待“const”的方法,使得它在用于变量和函数时具有相同的含义。此处不重要。

显示填充变量
name
的代码。
静态字符*gen\u name(…)
与您认为的不一样。@RaymondChen怎么会这样?(注:在