静态堆栈和动态堆栈在内存管理上有什么区别?

3
  1. 静态存储区域的大小在执行期间保持不变,但动态栈会随着激活记录的推入和弹出而增长和缩小。
  2. 在静态栈中,存储需求在执行前已知,但在动态栈中,栈帧的大小和结构在编译时已知,但实际内容和分配时间直到运行时才知道。

还有什么其他的差异,并且有人可以帮我提供一段代码片段吗? 谢谢。


你的问题并不清楚。 - user3344003
静态栈和动态栈的区别,不涉及数据结构,而是关于内存管理。 - Hunterr
猜测问题的一部分是,您所说的“静态堆栈”是什么意思? - user3344003
1个回答

2

我能够提供一些见解,因为我目前正在开发一种使用静态栈的系统。

由于您提到了堆栈帧,您必须知道堆栈用于在进入更深层次的子程序时跟踪上下文。仅明确提及这一点是因为它与下一段相关。

通常,堆栈和堆被视为动态的,这意味着它们可以扩展其大小 - 通常使用类似于malloc()等的内存管理来完成。这里展示了经典的图示(左面板)。正如您在中间面板中看到的那样,堆栈以井然有序的方式增长和缩小,因为内存只能在底部分配或释放。另一方面,堆可以在内部任何地方看到内存被分配/释放。当两个区域相遇时会发生冲突 - 这将导致一个大问题,因为无法调用更多的子例程。此外,很难预测这种情况何时会发生。

如果您想避免这种问题(例如在安全关键应用中),您可以选择禁止在堆栈+堆中使用动态内存。当您有信心您的程序永远不会超过特定深度的子例程调用时(例如没有递归,或递归被限制),使用静态堆栈是一个好的选择。使用静态堆栈也简化了实现,这是您在裸机应用程序中可能会关注的。

以下代码是如何在启动代码中实现静态堆栈的小例子:

//*****************************************************************************
//
// 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
}

您可以看到,在这种情况下,堆栈不会位于堆的旁边...静态堆栈可以放在任何地方,因为假设您永远不会超出其边界。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接