首页 > 解决方案 > 在 C 中的多个位置定义的全局符号的内存分配

问题描述

对于共享相同名称的全局定义,我们是否为每个定义分配内存?链接器会影响我们为这些全局符号分配内存的方式吗?

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

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

2.链接器解析多处定义的同名全局符号后,我们只为一个定义分配内存。

其中一个正确吗?

例子:

公元前

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

交流

#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 中的数据未初始化,它们也将始终设置为默认值而不是垃圾值。这是正确的吗?

标签: cglobal-variables

解决方案


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

如果将extern声明放入单独的翻译单元并将它们编译为单独的目标文件,则只有包含定义的文件int x = 15213;会分配内存,而不是包含声明的文件int x;。写作extern int x;可能更容易记住x其他地方定义的内容。如果你写了两个定义x并试图链接它们,链接器会给你一个错误。


推荐阅读