C语言全局变量在堆还是栈?(附带示例)
在C语言中,全局变量既不在堆上,也不在栈上,而是存储在程序的数据段中,这是可执行程序内存布局的一个特定区域。
为了更好地理解全局变量的存储位置,我们需要深入探讨 C 程序的内存布局。C程序的内存布局通常包含以下几个主要部分:
代码段(Text Segment) 数据段(Data Segment) - 已初始化数据段(Initialized Data Segment) - 未初始化数据段(Uninitialized Data Segment,也称为 BSS) 堆(Heap) 栈(Stack)
代码段存储程序的可执行指令,数据段用于存储全局变量和静态变量,堆用于动态内存分配,而栈用于存储局部变量和函数调用信息。
全局变量根据其初始化状态,会被存储在数据段的不同部分:
-
已初始化的全局变量:这些变量被存储在已初始化数据段中,例如,
int global_var = 10;
这样的全局变量会被放在这个区域。 -
未初始化的全局变量:这些变量被存储在未初始化数据段(BSS)中,例如,
int global_var;
这样的全局变量会被放在这个区域。BSS 段在程序启动时会被自动初始化为零。
为了更直观地理解这一点,让我们看一个简单的 C 程序示例:
#include <stdio.h> int initialized_global = 42; // 存储在已初始化数据段 int uninitialized_global; // 存储在未初始化数据段(BSS) void function() { static int static_var = 10; // 也存储在已初始化数据段 int local_var = 5; // 存储在栈上 } int main() { int* dynamic_var = malloc(sizeof(int)); // 分配在堆上 *dynamic_var = 20; printf("Initialized global: %d\n", initialized_global); printf("Uninitialized global: %d\n", uninitialized_global); function(); free(dynamic_var); return 0; }
在这个例子中,initialized_global 和 uninitialized_global 都是全局变量,但它们存储在数据段的不同部分。static_var 虽然是在函数内部定义的,但由于它是静态变量,也会被存储在数据段中。local_var 是局部变量,存储在栈上。dynamic_var 指向的内存则是在堆上动态分配的。
当我们运行这个程序时,输出结果可能如下:
Initialized global: 42 Uninitialized global: 0
注意,未初始化的全局变量 uninitialized_global 被自动初始化为 0,这是因为它存储在 BSS 段中。
全局变量存在于程序的整个生命周期中,这意味着它们会一直占用内存,直到程序结束。相比之下,栈上的局部变量只在其作用域内存在,而堆上的动态分配内存可以在不需要时释放。因此,过度使用全局变量可能会导致内存使用效率低下,并增加程序的复杂性。