【问题标题】:Understanding how scoped arrays are stored了解作用域数组的存储方式
【发布时间】:2020-05-31 03:16:52
【问题描述】:

我很困惑当数组在函数等中时,它们是如何存储在可执行文件中的。

通过下面的代码,我相信要存储三个整数的值的空间是在可执行文件中创建的。

#include <stdlib.h>

int main() {
    int arr[] = {rand(), rand(), rand()};
}

我在考虑函数中的数组,每个调用都将使用与其他调用相同的空间来存储它们的数组。但后来我认为递归调用会覆盖彼此的数组。我不明白如何为它们留出空间,尤其是在递归和未知数量的调用中。我试着举个例子:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool myfunc(unsigned val) {
    int arr[] = {rand() % 10, rand() % 10};

    if (val == 0)
        return true;

    myfunc(val - 1);

    printf("%d %d\n", arr[0], arr[1]);
    return false;
}

int main() {
    myfunc(rand() % 50);
}

我得到数组元素一个接一个地存储。但是当不知道会有多少空间时,它们(在堆栈中)如何有空间?

【问题讨论】:

  • 堆栈空间不是在编译时分配的,而是在运行时调用时分配的,所以无论调用多少次函数或是否递归都无关紧要。堆栈帧的总大小在编译时计算,当函数被调用时,stack_frame_size 字节在堆栈上分配,堆栈指针也相应调整。这足以解决混乱吗?

标签: c arrays recursion memory


【解决方案1】:

在具有自动存储(不带static关键字)的函数体中使用本地范围定义的对象存储在临时存储中,并在退出相应范围时自动回收。

典型的现代架构为此使用运行时堆栈:如果在编译时知道大小,堆栈指针寄存器在进入范围时会递减固定数量,就像您的示例一样:int arr[] = {rand() % 10, rand() % 10}; 定义一个数组2 个int,通常为 8 个字节。

如果仅在运行时知道大小,则堆栈指针会按运行时计算的值递减,如果此大小太大,可能会导致未定义的行为。堆栈指针在离开函数时恢复到原来的值。

【讨论】:

  • @GGG:如果这个答案有帮助,您可以通过点击其分数下方的灰色复选标记来接受它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 2017-05-10
  • 2019-02-19
  • 1970-01-01
  • 2017-09-12
  • 2018-04-01
相关资源
最近更新 更多