在嵌入式系统中,堆与栈通常表示操作系统对进程占用的两种管理方式,而RTOS中栈更为重要,每一个链路都要有自己的栈。因此对堆和栈的概念进行了些区分和了解。以下是自己学习总结的一些,如有不对的地方请指正:
(1)管理方式
①栈:由操作系统自动分配释放,无需手动控制;
②堆:由程序员控制堆的申请和释放工作(可能会产生内存泄漏)。
(2)空间大小
①每个进程拥有的栈大小都远小于堆。
(3)内存地址
①栈:栈的内存地址由高到低的,声明在前面的变量地址比声明在后面的变量地址更大;
②堆:堆的内存地址由低到高的,声明在前面的变量地址比声明在后面的变量地址更小。
(4)分配不同
①栈:既有动态分配也有静态分配;
②堆:堆只能动态分配。
(5)存储内容
①栈:存放函数的返回地址、相关参数、局部变量以及寄存器内容等。参考韦东山的视频课程。一般每个链路都有自己的一个栈,每个栈里都会为调用的函数开辟一段空间,开辟空间的地址是从高到低。以下图为例,在main函数中调用到a_fun函数时,首先会为a_fun在这个栈中开辟一段N字节的空间,这个空间会存储a_fun的返回地址(即a_fun函数下一行return 0)以及局部变量。其中局部变量的计算也在这个空间中进行。当在a_fun函数中调用到b_fun函数时,也会将c_fun函数作为返回地址存储在LR寄存器中(b_fun函数在栈开辟的空间中),并存储涉及到的局部变量。静态变量是不入栈的,一般在数据段或者BSS段。
②堆:一般堆顶使用一个字节的空间来存放堆的大小,具体存放内容是由程序员来填充。相比于栈的应用广泛(函数调用,返回地址、存储局部变量的地址(EBP)、实参和局部变量)等,堆更适合在分配大量的内存空间的时候使用。