【问题标题】:Static memory allocation of array at compile time编译时数组的静态内存分配
【发布时间】:2014-07-27 09:06:46
【问题描述】:

编译器如何在编译时确定下面数组的大小?

int n;
scanf("%d",&n);
int a[n];

它与动态分配有何不同(除了动态数组在堆中分配内存)。

如果可能,请根据激活堆栈内存映像解释这个数组是如何分配内存的。

【问题讨论】:

    标签: c


    【解决方案1】:

    数组的大小不是在编译时确定的;它是在运行时确定的。在分配数组时,n 具有已知值。在程序堆栈上分配自动变量的典型实现中,堆栈指针将被调整以为那么多整数腾出空间。它成为堆栈帧的一部分,并在超出范围时自动回收。

    此代码在 C90 中无效; C90 要求在块的开头声明所有变量,因此不允许混合声明和这样的代码。 C99 中引入了可变长度数组以及混合代码和声明。

    【讨论】:

    • 对不起,sizeof 运算符为非可变长度数组提供了整个数组的大小,这让我认为这仅适用于可变长度数组。
    • @ThoAppelsin: sizeof 是变长数组的特殊用途。
    【解决方案2】:

    在 C 中,分配类型的正确名称是自动。在计算术语中,术语 stack 有时用作同义词。

    a 的存储从定义点 int a[n]; 直到封闭范围的末尾(即当前函数的末尾或更早)都有效。

    它与int a[50]; 相同,只是可以分配与50 不同数量的整数。

    使用自动数组(有或没有运行时大小)的一个缺点是没有可移植的方法来防止堆栈溢出。 (实际上,自动变量的堆栈溢出是 C 标准根本没有解决的问题,但在实践中却是一个真正的问题。

    如果您要使用动态分配(即malloc 和朋友),那么它会通过返回NULL 让您知道内存是否不足,而堆栈溢出是令人讨厌的。

    【讨论】:

    • 实际上,malloc 也可能不会让您知道是否没有足够的可用内存。 Linux 的惰性分配器可能会报告成功,然后在您尝试实际访问您应该分配的内存时终止您的程序。
    • 确实如此。但它仍然比堆栈溢出更整洁(并且通常在运行之前有更多可用空间)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    相关资源
    最近更新 更多