c - 何时/何处分配本地数组?
问题描述
https://www.gnu.org/software/libc/manual/html_node/Memory-Allocation-and-C.html描述了局部变量的自动分配。我知道局部变量通常分配在堆栈上。我可以想象如何int
在堆栈上分配一个;只是推动它的价值。但是如何分配数组呢?
例如,如果您声明一个数组char str[10];
,那 10 个字节的空间是在堆栈上,还是在其他地方分配,只有str
指针被压入堆栈?如果是后者,这 10 个字节的空间分配在哪里?
此外,包括数组在内的局部变量究竟是什么时候分配的?我通常将堆分配称为“动态分配”,这意味着自动变量不是动态分配的。但是自动变量可以在控制流结构和函数体中声明,因此编译器不可能在运行前确切知道自动变量将占用多少空间。所以自动变量也必须是动态分配的,对吧?
编辑:我想强调这个问题的前半部分。我最感兴趣的是了解何时何地分配本地数组的空间。在堆栈上?别的地方?
编辑 2:当我最初为这个问题包含 C++ 标记时,我犯了一个错误。我的意思是只询问C语言及其实现。对于任何混淆,我深表歉意。
解决方案
在 C 2018 标准中,第 6.2.4 条第 6 和第 7 段告诉我们具有自动存储持续时间的对象的生命周期。第 6 段涵盖了不是可变长度数组的对象:
…它的生命周期从进入与其关联的块开始,直到该块的执行以任何方式结束。(进入封闭的块或调用函数会暂停,但不会结束当前块的执行。)如果递归地进入块,则每次都会创建对象的新实例。
因此,如果我们有以下代码:
{
PointA;
int x = 3;
PointB;
}
那么x
一旦执行到达就存在于C模型中PointA
——进入它的块,这就是生命周期x
开始的时候。然而,虽然x
已经存在于PointA
,但它的值是不确定的。初始化仅在达到定义时发生。
第 7 段告诉我们可变长度数组:
…它的生命周期从对象的声明开始,直到程序的执行离开声明的范围。
所以,如果我们有这个代码:
{
PointA;
int x[n]; // n is some variable.
PointB;
}
那么x
不存在于PointA
。它的生命周期从int x[n];
到达时开始。
请记住,这种存在只是根据 C 的抽象计算模型。只要可观察的结果(例如程序的输出)相同,编译器就可以优化代码。x
因此,当输入块时,编译器生成的实际代码可能不会创建。(它可能根本不会创建x
;它可以完全优化掉。)
推荐阅读
- flutter - Flutter 路由问题和重复的 GlobalKey
- node.js - 仅支持 HTTP(S) 协议 Firebase 函数
- python - 将“项目”从一个字典移动到一个新列表
- python - 如何在 np.roll() 上使用函数,例如 DataFrame.rolling().apply(function) 或 dataframe.rolling().agg(function)?
- azureservicebus - Azure 函数服务总线没有属性 application_properties
- javascript - 如何用父进程包装程序以便我可以在 nodejs 中重新启动?
- javascript - CSS过渡仅在第一个动画上不起作用
- c++ - Qt 应用程序无法仅使用 Qt 6.2 静态构建打印 QDocument
- flask - 在生产站点上未使用 flask migrate 后,如何使用 flask migrate 升级 PostgreSQL Heroku 数据库?
- html - 如何在图像旁边制作文字