【嵌入式C内存管理】

记录嵌入式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文件),检查数组的操作是否正确。

在这里插入图片描述

除了堆区,其他几个区都是有编译器和系统运行时自动处理的,而堆区由开发者来操作的。这既是便利,也是隐患,一旦操作失误就是内存泄漏或溢出。

1.2 项目实战------------堆和栈的使用和分配

【场景描述】

嵌入式Linux,在一个任务中,初始化一个较大的局部变量 char arry[1024*1024]1M 的内存空间

while(1) 里面一直获取数据到一片地址,使用memcpy进行数据拷贝,从char型数组中拷贝出去,代码会一直segmentstion fault段错误

void main(){
	char arry[1024*1024] = {0};  // 申请 1M 的内存空间
	char uart_buff[1024];  // 1024 字节 接收串口收到的数据
    char cnt = 0;
	while(1){
		uart_receive(uart_buff,1024); // 串口每次接收 1024 个数据
        memcpy(arry[1024*cnt],uart_buff,1024);
        cnt++;
	}
}

【问题调试】

若以上问题,不在栈分配空间,而使用 malloc 动态分配堆的空间,则不报错误

【问题分析】

segmentstion fault段错误肯定是 堆栈的问题;但是如果堆栈有问题的话,在最开始申请char数组的时候就会申请不到啊,运行就会出问题,而不应该在多次调用memcpy之后才出问题

  • 变量在定义的时候不会报错,在实际使用的时候会由于空间不足报错
  • 压栈操作是在运行中进行的,当你当前栈呀不进去了就溢出
  • 栈的大小一般也就几M

【注意事项】

存储方式:栈内存采用“ 先进后出”的存储方式,而堆内存采用 随机存储的方式。

空间大小:栈内存的空间 远小于 堆的内存空间。堆可以在需要时 动态增长,而战的大小是 固定的。而栈的大小受限于系统分配的栈空间,通常为2MB或更小。

访问速度:由于栈内存的存储方式较为简单,访问速度比堆内存快。访问栈的速度 远大于 访问堆的速度

参考资料

动态内存管理及防御性编程

堆和栈的区别?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积跬步、至千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值