ARM架构下内存与指针和堆栈的关系

ARM架构与FreeRTOS中的内存管理(flash与SRAM,堆栈)-CSDN博客

栈顶指的是当前栈指针(Stack Pointer, SP)所指向的内存地址。栈底指的是栈的起始地址,也就是栈区域在内存中的最低地址。在一个空栈中,栈顶是没有元素的,通常被定义为 -1 或 NULL。

对比看指针,当我们定义一个指针变量的时候,初值一定要将他赋成NULL,明确指针没有指向任何有效的内存地址,如果未初始化指针变量,指针变量会指向一个随机的内存地址,这个地址可以是一个已经被使用的地址,如果试图通过这个指针访问或操作这个内存区域,可能会导致程序崩溃,出现段错误(Segmentation Fault)。指针变量的起始地址就是栈底的地址。栈指针(SP)的变化,反映了指针变量在栈上的位置变化。

关于MCU的内存与指针,数组,函数的关系与操作:

第一,指针保存的是MCU的内存单元的地址,通过指针操作内存,如果第一次定义, 那么int *ptr 就代表这个地址,如果第一次是 int *ptr = NULL;那么接下来 ptr 就代表这个指针的地址。如果我定义了一个指针 *ptr,要想获取这个指针变量的地址就要用 &ptr,要想获取这个指针变量的数据就要用 *ptr,这里的”*“代表的是解引,与我们第一次定义的指针变量的“ * ”不是一个含义。

如果我想让指针变量 *ptr 指向变量 value 在内存中的地址,需要用 int *ptr = &value,因为指针 int *ptr 代表的是物理地址(如果是A核就是逻辑地址,MCU一般没有MMU就是物理地址),或者int *ptr = NULL;ptr = &value

 

第二,在代码中定义一个数组,数组第一个元素的地址就是整个数组在内存中的起始地址,数组的各个元素在内存中是连续存放的,如果想知道数组的地址,用取地址运算符&来获取数组元素的地址,例如&array[i]可以得到数组第i个元素的地址,array[i] 获取的是数组中的数据。如果用指针访问数组,那就是说要将我们定义的指针变量的地址指向数组的起始地址,也就是 int *ptr = &arr[0] 或 int *ptr = arr。

 

第三,指针函数与函数指针

指针函数:是一个返回指针类型的函数,比如:int *get_max(int a, int b) { return &a; } ,他的返回值是一个地址,

函数指针:是一个指向函数的指针变量,比如:int (*ptr_max)(int, int) = get_max; 相当于用函数指针调用指针函数,也就是将指针函数返回的地址赋值给函数指针,也就相当于int (*ptr_max)(int, int) 变成了一个指针变量,相当于 int *ptr_Value = ptr_max(a, b); 或者 int *ptr_Value = NULL; ptr_Value = ptr_max(a, b);

 

一般在MCU中使用指针函数与函数指针的情况是在“回调函数”,“数据结构和算法”等。

举例回调函数,理解实现意图,用数组举例说明

定义一个数组,

数组的起始地址传递给指针变量

将指针变量当成数组用,获取当中的数据

举例指针函数

野指针常见的产生原因:

  • 指针变量初值没有赋成NULL。
  • 当函数返回时,它的堆栈会被销毁,其中的局部变量也就不再有效。但如果在函数外部还持有一个指向该局部变量的指针,它就会变成野指针。
  • 如果通过指针访问数组元素时,下标越界访问了数组之外的内存,也会产生野指针。
  • 当一个动态分配的内存块被释放(free)后,指向该内存块的指针就变成了野指针。

堆栈溢出常见的产生原因:

堆栈溢出相当于数组越界,栈内存用于存储函数调用的上下文信息和局部变量。

  • 局部变量占用过多内存,超出任务定义的堆栈大小。
  • 递归(递归调用就是一个函数在自己内部再次调用自己)调用深度过深或函数调用层次过深。
  • 函数没有返回,没有 return 语句意味着函数无法主动返回,它创建的栈帧也无法被正常销毁,函数的栈帧会不断增加,造成栈空间耗尽,最终导致栈溢出(Stack Overflow)错误。
  • 无限循环,每次循环都会在栈上压入新的栈帧。

内存泄漏常见的产生原因:

【C语言】你对动态内存分配有多少了解呢_什么是动态内存分配-CSDN博客

内存泄漏是指程序在动态分配内存后,没有在适当的时候释放或销毁这些内存,导致内存被占用但无法再次利用的情况。随着程序运行时间的增长,被泄漏的内存会越来越多,直到耗尽系统的所有可用内存,从而导致程序崩溃或严重性能下降。内存泄漏通常发生在堆内存中,而不是栈内存中。

  • 程序动态分配内存后,忘记在合适的时候释放或销毁这些内存空间。
  • 复杂的数据结构(如链表、哈希表等)中,如果在删除元素时忘记清理相关引用,也会导致内存泄漏。

FreeRTOS 提供了功能和机制来帮助管理和检测内存泄漏,钩子函数(Hooks),内存保护(MPU),内存泄漏检测(Memory Leak Detection),内存状态跟踪(Memory Status Tracking)

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

梅尔文

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

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

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

打赏作者

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

抵扣说明:

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

余额充值