为什么我们不能在堆栈上分配动态内存?
为什么我们不能在堆栈上分配动态内存?
在栈上分配东西很棒,因为我们有RAII,不必担心内存泄漏之类的问题。但是有时我们必须在堆上分配:
- 如果数据太大(推荐)-因为栈很小。
- 如果要分配的数据的大小只在运行时知道(动态分配)。
两个问题:
- 为什么我们不能在堆栈上分配动态内存(即运行时仅知道大小的内存)?
- 为什么我们只能通过指针引用堆上的内存,而栈上的内存可以通过普通变量引用? 即:
Thing t;
。
编辑:我知道一些编译器支持可变长度数组-即动态分配的栈内存。但那真的是一般规则的例外。我想了解为什么通常我们不能在堆栈上分配动态内存的根本原因-它的技术原因和理由。
admin 更改状态以发布 2023年5月24日
为什么我们不能在栈上分配动态内存(即只知道在运行时大小的内存)?\n\n这更加复杂。每个栈帧的大小都被编译过的程序固定下来,因为完成的可执行文件需要包含某种类型的指令才能正常运行。例如,函数本地变量的布局和其他东西都是通过其低级汇编代码描述的寄存器和内存地址在程序中硬编码的:“变量” 实际上不存在于可执行文件中。让这些“变量”的数量和大小在编译运行之间改变会极大地复杂化这个过程,尽管这并不完全不可能(正如你已经发现的非标准可变长数组)。\n\n为什么我们只能通过指针引用堆上的内存,而可以通过普通变量引用栈上的内存?\n\n这仅仅是语法的结果。C++的“普通”变量恰好是具有自动或静态存储期的变量。语言的设计人员本来可以让你编写 `Thing t = new Thing` 这样的代码,然后整天使用 `t`,但他们没有这样做;同样,这将是更难实现的。那么你如何区分不同类型的对象呢?记住,你的已编译可执行文件必须记住自动销毁一种而不是另一种种类型的对象。\n\n我很愿意详细解释为什么和为什么不会有这些难题,因为我相信这就是你在这里追求的。不幸的是,我的汇编知识太有限了。