记录嵌入式C内存划分,后续会更新动态内存管理
1. 内存划分
- 栈区 stack有时也称为堆栈,重点在栈字,存放函数内部临时变量
- 堆区 heap也就是动态申请(malloc)、释放(free)的内存区域
- 数据区 data初始化的全局变量和静态变量, 占用可执行文件空间;rodata 固定不变const修饰的全局变量,不占内存空间
- bss区未初始化的全局变量、静态变量(static关键字描述的),初始化为全0的全局变量,不占用可执行文件大小
- 代码区 text程序二进制文件
1.1 栈区域内存测试
#include <stdio.h>
int main(void)
{
int a=100;
int b[3]={0};
int c=200;
printf("ori> a[%p]=%d,c[%p]=%d\r\n",&a,a,&c,c);
printf(" > b[%p]\r\n",&b);
b[0]=0;
b[1]=1;
b[2]=2;
b[3]=3;//error ->a
printf("new> a[%p]=%d,c[%p]=%d\r\n",&a,a,&c,c);
return 0;
}
运行结果:
ori> a[0028FEBC]=100,c[0028FEAC]=200
> b[0028FEB0]
new> a[0028FEBC]=3,c[0028FEAC]=200
结合打印的变量地址,栈空间分配如下图,因为数组b的操作越界,导致了变量a的值被覆盖。图片针对个人情况,一般情况下内存溢出都是使用数组越界,所以在异常值后或者前查看有没数组(全局变量可以查map文件),检查数组的操作是否正确。
除了堆区,其他几个区都是有编译器和系统运行时自动处理的,而堆区由开发者来操作的。这既是便利,也是隐患,一旦操作失误就是内存泄漏或溢出。
参考资料
动态内存管理及防御性编程