以下是 Compilers: Principles, Techniques, and Tools 的摘录。它涉及过程激活记录中可变长度数据项的处理。
Pascal is almost unique among languages in requiring that arrays local to a procedure have a length that can be determined at compile time. More often, the size of a local array may depend on the value of a parameter passed to the procedure. In that case, the size of all the data local to the procedure cannot be determined until the procedure is called.**
A common strategy for handling variable-length data is suggested in Fig. 7.15, where procedure
p
has three local arrays. The storage for these arrays is not part of the activation record forp
; only a pointer to the beginning of each array appears in the activation record. The relative addresses of these pointers are known at compile time, so the target code can access array elements through the pointers.Also shown in Fig. 7.15 is a procedure
q
called byp
. The activation record forq
begins after the arrays ofp
, and the variable-length arrays ofq
begin beyond that.
在上面摘录的第一部分中,文本讨论了 Pascal 的功能。编程语言,然后他们讨论相同的可能实现。现在我不熟悉 Pascal,想了解一下 C 中处理情况的方式。
我知道可以使用 malloc() 在 C 中动态创建数组及其姐妹函数,这会导致在堆上分配内存并将指向第一个字节的指针返回给我们。这根本不是问题。
如果我们在 C 中创建数组,其中数组的大小是一个常量,如下所示:
int function() {
int a[100];
}
然后该数组被放置在激活记录的本地数据部分,如下所示:
在上面的示例中,数组a
的大小在编译时就已知。这没有任何问题。
现在的情况:
More often, the size of a local array may depend on the value of a parameter passed to the procedure. In that case, the size of all the data local to the procedure cannot be determined until the procedure is called.
情况1:
现在让我们考虑下面的代码:
int function(int n) {
int a[n];
}
int main() {
function(10);
}
现在在上面的情况下,函数参数n
的大小可以在编译时知道,因此数组a
的大小虽然可以是变量在编译时已知。按照这个逻辑,C 是否按照龙书图7.15所示的方式分配上面的数组a
?
情况2:
int function(int n) {
int a[n];
}
int main() {
int x;
scanf("%d", &x);
function(x);
}
现在,在上述情况下,函数的参数n
的大小只能在运行时知道(?)或者仍然是上述情况,即,在编译时已知? 现在在这段代码中,数组a
分配在哪里。堆还是栈?
我去了here , here和 here ,但我没有找到我正在寻找的解释...
这里我说的是C99 .
最佳答案
一般来说,C 实现分配 VLAs在堆栈上,而不是在单独的堆数据结构中,但这实际上并不是标准所要求的。
由于 VLA 的大小仅在运行时已知,这意味着您将获得此类函数的可变大小的激活记录。激活记录如何分配和布局的细节往往取决于目标机器及其 ABI ,因此尝试将其分解(如上面的图表所示)对于不同的编译器和体系结构来说将是非常不同的。
关于arrays - 了解处理可变长度数据,特别关注 C(99) 中的可变长度数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66891948/