- 静态存储区域的大小在整个执行过程中保持不变,但动态堆栈会随着激活记录的推送和弹出而增长和收缩。
- 在静态堆栈中执行之前已知的存储要求,但 int 动态堆栈堆栈帧的大小和结构在编译时已知,但实际内容和分配时间直到运行时才知道。
还有什么不同之处,任何人都可以帮助我提供代码片段。 谢谢。
最佳答案
我可以在这里插一句,因为我目前正在开发一个采用某种静态堆栈的系统。
既然你提到了栈帧,你一定知道当你进入更深层嵌套的子程序时,栈是用来跟踪上下文的。只需在下一段中明确提及此 b/c 即可。
通常,堆栈和堆被视为动态,这意味着它们可以扩展大小 - 通常通过 malloc()
等方式进行内存管理。 classic illustration is show here (left panel) .正如您在中间面板中看到的那样,堆栈以组织良好的方式增长和收缩,因为只能在底部边缘分配或释放内存。另一方面,堆可以看到内部任何地方分配/释放的内存。当两个区域相遇时会发生碰撞——这将导致一个大问题,因为无法调用更多的子程序。此外,很难预测这种情况何时会发生。
如果您想避免此类问题(例如在安全关键型应用程序中),您可以选择禁止在堆栈和堆中的一个或两个中使用动态内存。使用静态堆栈的好时机是当您确信您的程序永远不会超过子例程调用的特定深度时(例如,没有递归,或者递归被限制)。使用静态堆栈还可以简化实现,这是您在裸机应用程序上可能会关心的问题。
以下代码是如何在启动代码中实现静态堆栈的一个小示例:
//*****************************************************************************
//
// Reserve space for the system stack.
//
//*****************************************************************************
__attribute__ ((section(".stack")))
static uint32_t g_pui32Stack[1024];
section
属性允许您使用链接描述文件在内存中定位堆栈:
ENTRY(Reset_Handler)
MEMORY
{
FLASH (rx) : ORIGIN = 0x0000C000, LENGTH = 960K
SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K
}
SECTIONS
{
.text :
{
/* This is where executable code gets stored */
} > FLASH
/* User stack section initialized by startup code. */
.stack (NOLOAD):
{
. = ALIGN(8);
*(.stack)
*(.stack*)
. = ALIGN(8);
} > SRAM
.data :
{
/* This is where global/static initialized variables are stored */
} > SRAM AT>FLASH
.bss :
{
/* This is where global/static 0-filled variables are stored */
} > SRAM
.heap (COPY):
{
/* This is where dynamically allocated storage could be used */
} > SRAM
}
你可以看到,在这种情况下,堆栈并不位于堆的旁边......静态堆栈可以放在任何你想要的地方,因为假设你永远不会超出它的边界。
关于memory-management - 在内存管理上下文中,静态堆栈和动态堆栈有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31603532/