编译器在编译时不知道大小如何分配内存? [英] How does the compiler allocate memory without knowing the size at compile time?

查看:44
本文介绍了编译器在编译时不知道大小如何分配内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wrote a C program that accepts integer input from the user, that is used as the size of an integer array, and using that value it declares an array of given size, and I am confirming it by checking the size of the array.

代码:

#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的值是未知的,那么编译器为什么能够分配所需大小的内存呢?

and surprisingly it is correct! The program is able to create the array of required size.
But all static memory allocation is done at compile time, and during compile time the value of n is not known, so how come the compiler is able to allocate memory of required size?

如果我们可以这样分配所需的内存,那么使用malloc()calloc()动态分配有什么用?

If we can allocate the required memory just like that then what is the use of dynamic allocation using malloc() and calloc()?

推荐答案

这不是静态内存分配".您的数组 k 是一个可变长度数组 (VLA),这意味着该数组的内存是在运行时分配的.大小将由 n 的运行时值决定.

This is not a "static memory allocation". Your array k is a Variable Length Array (VLA), which means that memory for this array is allocated at run time. The size will be determined by the run-time value of n.

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

The language specification does not dictate any specific allocation mechanism, but in a typical implementation your k will usually end up being a simple int * pointer with the actual memory block being allocated on the stack at run time.

对于 VLA sizeof 运算符也在运行时进行评估,这就是您在实验中从中获得正确值的原因.只需使用 %zu(而不是 %ld)来打印 size_t 类型的值.

For a VLA sizeof operator is evaluated at run time as well, which is why you obtain the correct value from it in your experiment. Just use %zu (not %ld) to print values of type size_t.

malloc(和其他动态内存分配函数)的主要目的是覆盖适用于本地对象的基于范围的生命周期规则.IE.使用 malloc 分配的内存永远"保持分配状态,或者直到您使用 free 显式释放它为止.使用 malloc 分配的内存不会在块的末尾自动释放.

The primary purpose of malloc (and other dynamic memory allocation functions) is to override the scope-based lifetime rules, which apply to local objects. I.e. memory allocated with malloc remains allocated "forever", or until you explicitly deallocate it with free. Memory allocated with malloc does not get automatically deallocated at the end of the block.

如您的示例中所示,VLA 不提供这种破坏范围"的功能.您的数组 k 仍然遵守常规的基于范围的生命周期规则:它的生命周期在块的末尾结束.为此,在一般情况下,VLA 不可能替代malloc 等动态内存分配函数.

VLA, as in your example, does not provide this "scope-defeating" functionality. Your array k still obeys regular scope-based lifetime rules: its lifetime ends at the end of the block. For this reason, in general case, VLA cannot possibly replace malloc and other dynamic memory allocation functions.

但在特定情况下,当您不需要击败范围"而只需使用 malloc 来分配运行时大小的数组时,VLA 确实可能被视为 的替代品malloc.请再次记住,VLA 通常在堆栈上分配,并且在堆栈上分配大块内存直到今天仍然是一种相当有问题的编程实践.

But in specific cases when you don't need to "defeat scope" and just use malloc to allocate a run-time sized array, VLA might indeed be seen as a replacement for malloc. Just keep in mind, again, that VLAs are typically allocated on the stack and allocating large chunks of memory on the stack to this day remains a rather questionable programming practice.

这篇关于编译器在编译时不知道大小如何分配内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆