在C中多个位置定义的全局符号的内存分配

时间:2018-06-27 03:52:46

标签: c global-variables

对于具有相同名称的全局定义,我们是否为每个定义分配内存? 链接程序会影响我们如何为这些全局符号分配内存吗?

以下是我认为解决此问题的可能方法:

1。我们首先在程序中遇到全局变量时为其分配内存。 (每个定义都会有内存。)然后,链接程序将解析全局符号。

2。链接程序在多个位置解析具有相同名称的全局符号后,我们仅为一个定义分配内存。

其中之一正确吗?

示例:

b.c

#include <stdio.h>
#include "a.c"
void f(void);
int x = 15213;
int main()
{
  f();
  printf("x = %d\n", x);
  return 0;
}

a.c

#include <stdio.h>
int x;
void f()
{
  printf("x in f = %d\n", x);
  x = 15212;
}

以上代码已编译并运行,没有任何错误或警告。 这就是我得到的:

x in f = 0
x = 15212

我们在内存中有一个x定义还是两个?

与此相关的一个快速问题:

全局变量和静态变量在初始化时存储在数据段(DS)中,而在未初始化时存储在以符号开头的块(BSS)中。即使BSS中的数据未初始化,也将始终将其设置为默认值,而不是垃圾值。是这样吗?

2 个答案:

答案 0 :(得分:0)

如果两个.c文件中的每个文件都声明了自己的全局int x作为示例,则会在内存中分配两个不同的变量。

请注意,它们的作用域不同,因此不能从其他文件访问这些符号。也就是说,每个文件始终通过全局变量名称“ x”访问其自己的int x。

如果您尝试将全局变量替换为存在具有相同名称的全局变量的任何源文件,则您的编译器应该抱怨。

答案 1 :(得分:0)

由于一个C文件直接在另一个文件中#include -d,因此它们在同一翻译单元中。 (顺便说一下,不建议这样做-程序员习惯将头文件命名为*.h,而不是*.c,并且将*.c文件用于自己编译。)对于编译器,程序员只是将一个文件的内容复制粘贴到另一个文件中。前向声明为x,但只有一个定义。

如果将extern声明放入一个单独的转换单元中并将其编译成单独的目标文件,则只有包含定义int x = 15213;的对象才会分配内存,而不包含声明{{1 }}。编写int x;可能会更容易记住extern int x;是在其他地方定义的。如果您编写x的两个定义并尝试链接它们,则链接器将给您一个错误。