c++ - 为什么我们不能在栈上分配动态内存?

标签 c++ pointers memory-management heap-memory stack-memory

在堆栈上分配东西很棒,因为我们有 RAII,不必担心内存泄漏等问题。然而有时我们必须在堆上分配:

  • 如果数据真的很大(推荐)——因为栈很小。

  • 如果要分配的数据大小仅在运行时已知(动态分配)。

两个问题:

  1. 为什么我们不能分配动态内存(即大小为 仅在运行时知道)在堆栈上?

  2. 为什么我们只能通过指针引用堆上的内存,而栈上的内存可以通过普通变量引用? IE。 事物 t;

编辑:我知道一些编译器支持可变长度数组——这是动态分配的堆栈内存。但这确实是一般规则的异常(exception)。我有兴趣了解为什么通常我们不能在堆栈上分配动态内存的根本原因 - 其技术原因及其背后的理性。

最佳答案

Why can't we allocate dynamic memory (i.e. memory of size that is only known at runtime) on the stack?

实现这一点比较复杂。由于完成的可执行文件需要包含的指令类型才能工作,因此每个堆栈帧的大小都被嵌入到您的编译程序中。例如,你的函数局部变量的布局和诸如此类的东西,实际上是通过它在低级汇编代码中描述的寄存器和内存地址硬编码到你的程序中的:“变量”实际上并不存在于可执行文件中。让这些“变量”的数量和大小在编译运行之间发生变化会使这个过程变得非常复杂,尽管这并非完全不可能(正如您所发现的那样,使用非标准可变长度数组)。

Why can we only refer to memory on the heap through pointers, while memory on the stack can be referred to via a normal variable

这只是语法的结果。 C++ 的“正常”变量恰好是那些具有自动或静态存储持续时间的变量。该语言的设计者可以在技术上做到这一点,这样您就可以编写类似Thing t = new Thing 的东西,并且整天只使用t ,但他们没有;同样,这将更难实现。那么,如何区分不同类型的对象呢?请记住,您编译的可执行文件必须记住自动销毁一种而不是另一种。

我很乐意详细说明这些事情为什么困难以及为什么不困难,因为我相信这就是您在这里所追求的。不幸的是,我对汇编的了解太有限了。

关于c++ - 为什么我们不能在栈上分配动态内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26296228/

相关文章:

c++ - 面试中用C++写了两个分配和释放int数组的函数

c++ - 访问特定地址时是否可以强制访问冲突?

c++ - 识别两个函数

c++ - 处理多个功能文件时 Cucumber-cpp 上的链接器错误

c++ - 是否可以在运行时确定指针指向 C++ 类还是指向 Objective-C 类?

将 int 复制到不同的内存位置,接收比预期更多的字节

c++ - 如何从 BYTE* 读取一些字节

ios - UICollectionView 中的高内存使用率

c++ - 我可以在中断中使用 cli() 和 sei() 吗?

c++ - glibmm 超时信号