开发者社区> 问答> 正文

编译器如何在不知道编译时大小的情况下分配内存?

我编写了一个C程序,该程序接受用户的整数输入,用作整数数组的大小,并使用该值声明给定大小的数组,并通过检查数组的大小来确认它。

码:

#include <stdio.h> int main(int argc, char const *argv[]) { int n; scanf("%d",&n); int k[n]; printf("%ld",sizeof(k)); return 0; } 令人惊讶的是,这是正确的!该程序能够创建所需大小的数组。 但是所有静态内存分配都是在编译时完成的,并且在编译时n不知道的值,那么编译器怎么能分配所需大小的内存呢?

如果我们可以像这样分配所需的内存,那么使用malloc()和进行动态分配的用途是calloc()什么? 问题来源于stack overflow

展开
收起
保持可爱mmm 2020-02-09 12:01:12 613 0
1 条回答
写回答
取消 提交回答
  • 这不是“静态内存分配”。您的数组k是可变长度数组(VLA),这意味着该数组的内存在运行时分配。大小将由的运行时值确定n。

    语言规范没有规定任何特定的分配机制,但是在典型的实现中,您k通常最终将成为一个简单的int *指针,并在运行时在堆栈上分配实际的内存块。

    对于VLA sizeof运算符,还需要在运行时对其进行评估,这就是为什么您在实验中从中获得正确值的原因。只需使用%zu(而不是%ld)打印type的值size_t。

    malloc(和其他动态内存分配功能)的主要目的是覆盖适用于本地对象的基于范围的生存期规则。即,分配给内存的内存将malloc“永远”分配,或者直到您使用显式取消分配内存为止free。分配malloc有的内存不会在块的末尾自动释放。

    在您的示例中,VLA不提供这种“破坏范围”的功能。您的数组k仍然遵守常规的基于作用域的生存期规则:其生存期在块末尾结束。因此,在一般情况下,VLA无法替换malloc其他动态内存分配功能。

    但是在特定情况下,当您不需要“破坏作用域”而只malloc需要分配运行时大小的数组时,VLA确实可以被视为替代malloc。再次请记住,VLA通常是在堆栈上分配的,到目前为止,在堆栈上分配大块内存仍然是一个相当可疑的编程实践。

    2020-02-09 12:01:25
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
内存取证与IaaS云平台恶意行 为的安全监控 立即下载
云服务器ECS内存增强型实例re6全新发布 立即下载
低代码开发师(初级)实战教程 立即下载