为什么我们不能在堆栈上分配动态内存? [英] Why can't we allocate dynamic memory on the stack?

查看:349
本文介绍了为什么我们不能在堆栈上分配动态内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在堆栈上分配的东西真是棒极了,因为比起我们拥有RAII,不必担心内存泄漏之类的问题.但是有时我们必须在堆上分配:

Allocating stuff on the stack is awesome because than we have RAII and don't have to worry about memory leaks and such. However sometimes we must allocate on the heap:

  • 如果数据确实很大(建议)-因为堆栈很小.

  • If the data is really big (recommended) - because the stack is small.

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

If the size of the data to be allocated is only known at runtime (dynamic allocation).

两个问题:

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

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

为什么我们只能通过指针引用堆中的内存,而堆栈中的内存却可以通过普通变量引用呢? IE. Thing t;.

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? I.e. Thing t;.

我知道有些编译器支持可变长度数组-这是动态分配的堆栈内存.但这确实是一般规则的例外.我有兴趣了解导致通常无法在堆栈上分配动态内存的根本原因-它的技术原因以及其背后的合理性.

I know some compilers support Variable Length Arrays - which is dynamically allocated stack memory. But that's really an exception to the general rule. I'm interested in understanding the fundamental reasons for why generally, we can't allocate dynamic memory on the stack - the technical reasons for it and the rational behind it.

推荐答案

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

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

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

It's more complicated to achieve this. The size of each stack frame is burned-in to your compiled program as a consequence of the sort of instructions the finished executable needs to contain in order to work. The layout and whatnot of your function-local variables, for example, is literally hard-coded into your program through the register and memory addresses it describes in its low-level assembly code: "variables" don't actually exist in the executable. To let the quantity and size of these "variables" change between compilation runs greatly complicates this process, though it's not completely impossible (as you've discovered, with non-standard variable-length arrays).

为什么我们只能通过指针引用堆中的内存,而堆栈中的内存却可以通过普通变量引用

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,但是他们没有这样做;同样,这将更加难以实施.那么,如何区分不同类型的对象呢?请记住,您编译后的可执行文件必须记住要自动销毁一种而不是另一种.

This is just a consequence of the syntax. C++'s "normal" variables happen to be those with automatic or static storage duration. The designers of the language could technically have made it so that you can write something like Thing t = new Thing and just use a t all day, but they did not; again, this would have been more difficult to implement. How do you distinguish between the different types of objects, then? Remember, your compiled executable has to remember to auto-destruct one kind and not the other.

我很想详细说明为什么这些困难以及为什么不困难的细节,因为我相信这就是您要追求的.不幸的是,我对汇编的知识太有限了.

I'd love to go into the details of precisely why and why not these things are difficult, as I believe that's what you're after here. Unfortunately, my knowledge of assembly is too limited.

这篇关于为什么我们不能在堆栈上分配动态内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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