#include <stdio.h>
#include <stdlib.h>
int globalVar = 10; // 全局变量,存放在数据区
void func() {
static int staticVar = 20; // 静态局部变量,存放在数据区
int localVar = 30; // 局部变量,存放在栈区
int* heapVar = (int*)malloc(sizeof(int)); // 动态分配的内存,存放在堆区
if (heapVar != NULL) {
*heapVar = 40;
free(heapVar); // 释放堆区内存
}
}
int main() {
func();
return 0;
}
一个典型的程序在运行时,其内存结构可以大致划分为以下几个区域:
- 代码区(Code Segment)
- 内容:存放CPU执行的机器指令,即程序代码。
- 特点:代码区是只读的,以防止程序意外修改其指令。
- 示例:函数体、字符串常量等。
- 数据区(Data Segment)
- 数据区进一步细分为几个子区域,包括全局变量区、静态变量区等。
- 全局变量区:存放全局变量和静态全局变量。这些变量在程序启动时被分配内存,并在程序结束时由操作系统释放。
- 静态变量区:包括静态局部变量和静态全局变量。静态局部变量在函数调用结束后不释放,其值在下次函数调用时保持不变。静态全局变量只在本文件内可见。
- 特点:数据区中的变量在程序运行期间一直存在,直到程序结束。
- 栈区(Stack Segment)
- 内容:用于存放函数的局部变量、函数参数、返回地址等。
- 特点:栈是一种后进先出(LIFO)的数据结构,由编译器自动管理。函数调用时,会在栈上为其局部变量分配空间;函数返回时,这些空间会被自动释放。
- 限制:栈的大小有限,通常由操作系统在程序启动时确定,超出限制会导致栈溢出。
- 堆区(Heap Segment)
- 内容:用于存放程序运行期间动态分配的内存。
- 特点:堆区由程序员手动管理,通过
malloc
、calloc
、realloc
等函数分配内存,通过free
函数释放内存。堆区的大小相对较大,但管理复杂,容易出现内存泄漏等问题。 - 用途:适合存储大小不确定或生命周期与函数调用无关的数据。