首页 > 编程笔记 > C语言笔记

C语言全局变量在堆还是栈?(附带示例)

在C语言中,全局变量既不在堆上,也不在栈上,而是存储在程序的数据段中,这是可执行程序内存布局的一个特定区域。


为了更好地理解全局变量的存储位置,我们需要深入探讨 C 程序的内存布局。C程序的内存布局通常包含以下几个主要部分:

代码段(Text Segment)
数据段(Data Segment)
  - 已初始化数据段(Initialized Data Segment)
  - 未初始化数据段(Uninitialized Data Segment,也称为 BSS)
堆(Heap)
栈(Stack)

代码段存储程序的可执行指令,数据段用于存储全局变量和静态变量,堆用于动态内存分配,而栈用于存储局部变量和函数调用信息。


全局变量根据其初始化状态,会被存储在数据段的不同部分:


为了更直观地理解这一点,让我们看一个简单的 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 段中。
 

全局变量存在于程序的整个生命周期中,这意味着它们会一直占用内存,直到程序结束。相比之下,栈上的局部变量只在其作用域内存在,而堆上的动态分配内存可以在不需要时释放。因此,过度使用全局变量可能会导致内存使用效率低下,并增加程序的复杂性。

相关文章