在C语言中,内存的分配和管理是程序设计中超级重大的一部分。了解内存的不同分配区域,如栈区、堆区、全局区、常量区和代码区,对于编写高效、安全的程序至关重大。本文将围绕这个主题深入讲解C语言中这些内存分配区域的特点和用途。
C语言内存整体分布示意图如下:

内存整体分布图
1. 栈区(Stack)
栈区是由编译器自动管理的一块内存区域,用于存储局部变量和函数调用时的相关信息。栈区采用后进先出(LIFO)的方式进行数据存取,当函数被调用时,局部变量和函数参数被分配在栈上,当函数返回时,这些数据会被自动释放。
栈区的大小一般是固定的,而且相对较小。因此,过度递归或大量的局部变量可能导致栈溢出(Stack Overflow)的错误。为了避免这种情况,应该尽量避免过深的函数嵌套和过多的局部变量。
#include <stdio.h>
void foo() {
int x = 10; // x是局部变量,存储在栈区
printf("局部变量x的地址:%p
", &x);
}
int main() {
foo();
return 0;
}
2. 堆区(Heap)
堆区是由程序员手动分配和释放内存的一块区域。在堆区中,数据的生命周期由程序员控制,可以动态地分配和释放内存。堆区的大小一般较大,适合存储大量的动态数据。
在C语言中,可以使用malloc()和free()函数来在堆区进行内存分配和释放。需要注意的是,对于每次使用malloc()分配的内存块,都需要在不需要时使用free()释放,否则会导致内存泄漏。
#include <stdio.h>
#include <stdlib.h>
int main() {
int* ptr;
ptr = (int*)malloc(5 * sizeof(int)); // 在堆区分配5个整型的内存块
if (ptr == NULL) {
printf("内存分配失败
");
return 1;
}
// 使用分配的内存块
for (int i = 0; i < 5; i++) {
ptr[i] = i + 1;
printf("ptr[%d] = %d
", i, ptr[i]);
}
// 释放内存块
free(ptr);
return 0;
}
3. 全局区(Global)
全局区是用于存储全局变量和静态变量的一块内存区域。全局变量是在函数外部声明的变量,它的生命周期从程序的开始到结束。静态变量是在函数内部使用static关键字声明的变量,它的生命周期也从程序的开始到结束,但作用域仅限于所在的代码块。
全局区的内存分配在程序启动时完成,它的大小取决于全局变量和静态变量的数量和大小。在程序执行过程中,全局区的数据始终存在于内存中,不会因函数的调用和返回而改变。
#include <stdio.h>
int globalVar = 10; // 全局变量
void foo() {
static int staticVar = 20; // 静态变量
printf("全局变量globalVar的地址:%p
", &globalVar);
printf("静态变量staticVar的地址:%p
", &staticVar);
}
int main() {
foo();
return 0;
}
4. 常量区(Constant)
常量区是用于存储常量数据的一块内存区域,它的数据在程序执行期间不能被修改。常量区一般包含字符串常量和全局const常量。
#include <stdio.h>
const int constant = 100; // 全局const常量,存储在常量区
int main() {
const char* str = "Hello, World!"; // 字符串常量,存储在常量区
printf("%s
", str);
return 0;
}
5. 代码区(Code)
代码区是用于存储程序的机器指令的一块内存区域。在程序运行时,代码区的指令按照程序的逻辑顺序依次执行。代码区是只读的,程序不允许修改代码区的内容。
#include <stdio.h>
int add(int a, int b) {
return a + b; // 这部分代码存储在代码区
}
int main() {
int result = add(5, 3); // 这部分代码也存储在代码区
printf("5 + 3 = %d
", result);
return 0;
}
结论
本文围绕C语言中内存的分配和管理,深入讲解了栈区、堆区、全局区、常量区和代码区的特点和用途。栈区用于自动管理函数调用时的局部变量,堆区用于手动管理动态内存,全局区用于存储全局变量和静态变量,常量区用于存储常量数据,代码区用于存储程序的机器指令。了解这些内存分配区域,有助于编写高效、安全的C语言程序,并更好地理解C语言程序的执行过程和内存使用机制。
战区向下增长,堆区向上增长,不错学习了
明白了
局部变量是编译器分配?函数没被调用里面的局部变量提前分配?
这个内存布局和flash ram rom等是怎么对应的?代码不是放在flash上吗。
不错
C内存
是单片机都是这样分配的吗?
转
收藏了,感谢分享
谢谢鼓励