程序设计中的堆和栈

参考函数调用的基本原理,就可以大概知道两者的不同,下面总结以下。

栈(stack)是为执行线程留出的内存空间(每一个线程都有一个栈)
当线程创建的时候,操作系统(OS)为每一个系统级(system-level)的线程分配栈。栈附属于线程,因此当线程结束时栈被回收。当线程被创建的时候,设置栈的大小。

特点:

  1. 跟踪栈简单
  2. 从栈中释放块(free block)只不过是指针的偏移而已
  3. 在栈上的每个字节频繁的被复用也就意味着它可能映射到处理器缓存中
  4. 大小有限

堆(heap)是为动态分配预留的内存空间(每一个应用程序通常只有一个堆尽管为不同类型分配内存使用多个堆的情况也是有的))
通常情况下,操作系统通过调用语言的运行时(runtime)去为应用程序分配堆。堆通常通过运行时在应用程序启动时被分配,当应用程序(进程)退出时被回收。在应用程序启动的时候,设置堆的大小,但是可以在需要的时候扩展(分配器向操作系统申请更多的内存)。

特点:

  1. 跟踪堆困难
    和栈不一样,从堆上分配和重新分配块没有固定模式。因此,你可以在任何时候分配和释放它。这样使得跟踪哪部分堆已经被分配和被释放变的异常复杂;有许多定制的堆分配策略用来为不同的使用模式下调整堆的性能
    这里写图片描述
  2. 在堆上的变量必须要手动释放,不存在作用域的问题
  3. 大量的分配和释放可造成内存碎片
  4. 可以分配较大的内存
### STM32 中的概念 #### 的作用与配置方法 在嵌入式系统中,特别是像STM32这样的微控制器平台,用于动态内存分配。这意味着当程序运行时可以根据需求申请一定大小的连续存储区域。这种灵活性使得复杂的数据结构(如链表、树形结构等)能够被创建并管理。 对于STM32而言,默认情况下其启动文件已经定义了一定数量的空间作为heap区,并指定了起始地址。例如,在某些型号中可以看到如下设置: ```assembly HEAP 0x200106f8 Section 512 startup_stm32f2xx.o(HEAP)[^4] ``` 这表明从`0x200106f8`开始有512字节可用作空间。然而,实际应用过程中可能需要调整这个数值以适应具体应用场景的需求;如果应用程序频繁地进行大量的动态内存操作,则应适当增加容量以免发生溢出错误。 为了修改默认设定,可以在链接脚本(.ld)内重新指定heap段的位置及其长度。通常做法是在`.isr_vector`之后紧跟`.data`, `.bss`等静态数据段放置heap部分。 #### 的作用与配置方法 相比之下,主要用于函数调用期间保存返回地址、参数传递以及临时变量存储等功能。每当进入一个新的子过程执行前都会先压入当前上下文环境至顶位置以便后续恢复现场之需。因此随着递归深度加大或局部对象增多,所需占用的stack资源也会相应增长。 同样地,在startup代码中有预设好的STACK初始化语句: ```assembly STACK 0x200108f8 Section 1024 startup_stm32f2xx.o(STACK) ``` 上述片段说明了初始状态下为预留了自`0x200108f8`起共计1KB (即1024 bytes) 的RAM区间供使用。不过值得注意的是,由于大多数MCU内部SRAM总量有限,所以合理规划各模块间共享这部分宝贵资产显得尤为重要——过大的尺寸不仅浪费硬件资源还可能导致其他重要组件无法获得足够的工作缓冲区而引发异常状况。 针对不同版本系列的产品手册会给出建议性的最大允许范围值,开发者应当依据实际情况灵活调配二者之间的比例关系。另外一种有效手段就是借助编译工具生成的地图(map)文档来精确分析整个工程所消耗的具体情况从而做出最优决策[^5]。 ### C语言中的全局变量、局部变量区别于特性 除了理解本身外,掌握它们与其他类型的变量之间相互作用也是至关重要的知识点之一。简单来说: - **全局/静态变量** 存储于特定的数据段而非活动记录之中; - **自动型局部实体** 则完全依赖于对应层次框架内的私有工作区实现生命周期管理访问控制机制。 综上所述,通过精心设计布局方案可以显著提升系统的稳定性性能表现[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值