为什么要在堆而不是堆栈上分配内存?
可能的重复:
什么时候最好使用堆栈而不是堆,反之亦然?
我已经阅读了一些有关堆与堆栈的其他问题,但他们似乎更关注堆/堆栈的作用而不是为什么你会使用它们。
在我看来,堆栈分配几乎总是首选,因为它更快(只需移动堆栈指针而不是在堆中寻找可用空间),并且在使用完毕后不必手动释放分配的内存。我认为使用堆分配的唯一原因是,如果您想在函数中创建一个对象,然后在该函数范围之外使用它,因为从函数返回后,堆栈分配的内存会自动取消分配。
使用堆分配而不是堆栈分配还有其他我不知道的原因吗?
Possible Duplicate:
When is it best to use a Stack instead of a Heap and vice versa?
I've read a few of the other questions regarding the heap vs stack, but they seem to focus more on what the heap/stack do rather than why you would use them.
It seems to me that stack allocation would almost always be preferred since it is quicker (just moving the stack pointer vs looking for free space in the heap), and you don't have to manually free allocated memory when you're done using it. The only reason I can see for using heap allocation is if you wanted to create an object in a function and then use it outside that functions scope, since stack allocated memory is automatically unallocated after returning from the function.
Are there other reasons for using heap allocation instead of stack allocation that I am not aware of?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
原因有几个:
malloc
/calloc
到free< /代码>);
如果没有灵活的对象生存期,二叉树和链表等有用的数据结构实际上是不可能编写的。
There are a few reasons:
malloc
/calloc
tofree
);Without the flexible object lifetime, useful data structures such as binary trees and linked lists would be virtually impossible to write.
最重要的是#1。一旦你进入任何类型的并发,或者 IPC#1 就无处不在。如果没有一些堆分配,即使是大多数重要的单线程应用程序也很难设计。这实际上是在 C/C++ 中伪造一种函数式语言。
The big one is #1. As soon as you get into any sort of concurrency or IPC #1 is everywhere. Even most non-trivial single threaded applications are tricky to devise without some heap allocation. That'd practically be faking a functional language in C/C++.
所以我想制作一个字符串。我可以将其放在堆上或堆栈上。让我们尝试一下:
对于堆栈:
现在我将这两个字符串放在各自的位置。后来,我想让它们更长:
对于堆栈:
这只是一个好处,其他人提到了其他好处,但这是一个相当不错的好处。有了堆,我们至少可以尝试让我们分配的空间更大。有了堆栈,我们就只能坚持现有的东西了。如果我们想要增长空间,我们必须预先声明这一切,我们都知道看到这一点有多糟糕:
So I want to make a string. I can make it on the heap or on the stack. Let's try both:
And for the stack:
So now I have these two strings in their respective places. Later, I want to make them longer:
And for the stack:
This is only one benefit, and others have mentioned other benefits, but this is a rather nice one. With the heap, we can at least try to make our allocated space larger. With the stack, we're stuck with what we have. If we want room to grow, we have to declare it all up front, and we all know how it stinks to see this:
使用堆的最明显的理由是当您调用函数并需要返回未知长度的内容时。有时,调用者可能会将内存块和大小传递给函数,但在其他时候,这是不切实际的,特别是如果返回的内容很复杂(例如,指针飞来飞去的不同对象的集合等)。
The most obvious rationale for using the heap is when you call a function and need something of unknown length returned. Sometimes the caller may pass a memory block and size to the function, but at other times this is just impractical, especially if the returned stuff is complex (e.g. a collection of different objects with pointers flying around, etc.).
在很多情况下,尺寸限制是一个巨大的破坏因素。堆栈通常以低兆字节甚至千字节为单位(即堆栈上的所有内容),而所有现代 PC 都允许使用几 GB 的堆。因此,如果您要使用大量数据,则绝对需要堆。
Size limits are a huge dealbreaker in a lot of cases. The stack is usually measured in the low megabytes or even kilobytes (that's for everything on the stack), whereas all modern PCs allow you a few gigabytes of heap. So if you're going to be using a large amount of data, you absolutely need the heap.
只是添加
你可以使用 alloca 在堆栈上分配内存,但堆栈上的内存也是有限的,而且该空间仅在函数执行期间存在。
这并不意味着所有内容都应该分配在堆上。就像所有设计决策 这也有些困难,应该使用两者的“明智”组合。
just to add
you can use alloca to allocate memory on the stack, but again memory on the stack is limited and also the space exists only during the function execution only.
that does not mean everything should be allocated on the heap. like all design decisions this is also somewhat difficult, a "judicious" combination of both should be used.
除了手动控制对象的生命周期(您提到的)之外,使用堆的其他原因还包括:
例如,您可以分配一个特定大小的数组,该大小仅在运行时才知道。
随着 C99 中 VLA(可变长度数组)的引入,可以在不使用堆的情况下分配固定运行时大小的数组(这基本上是“alloca”功能的语言级实现)。然而,在其他情况下,即使在 C99 中,您仍然需要堆。
例如,当您构建二叉树结构时,您无法提前在堆栈上有意义地分配树的节点。您必须使用堆“按需”分配它们。
当您需要一个大的 I/O 缓冲区时,即使是很短的时间(在单个函数内),从堆中请求它比声明一个大的自动数组更有意义。
Besides manual control of object's lifetime (which you mentioned), the other reasons for using heap would include:
For example, you can allocate an array of certain size, which is only known at run time.
With the introduction of VLA (Variable Length Arrays) in C99, it became possible to allocate arrays of fixed run-time size without using heap (this is basically a language-level implementation of 'alloca' functionality). However, in other cases you'd still need heap even in C99.
For example, when you build a binary tree stucture, you can't meaningfully allocate the nodes of the tree on the stack in advance. You have to use heap to allocated them "on demand".
When you need a large, say, I/O buffer, even for a short time (inside a single function) it makes more sense to request it from the heap instead of declaring a large automatic array.
堆栈变量(通常称为“自动变量”)最适合用于您希望始终相同且始终较小的事物。
都是堆栈分配,这些也在编译时固定。
堆分配的最佳原因是您无法始终知道需要多少空间。您通常只有在程序运行后才知道这一点。您可能知道限制,但只想使用所需的确切空间量。
如果您必须读取一个从 1k 到 50mb 的文件,您不会这样做:-
会尝试在堆栈上分配 50mb,这通常会失败,因为堆栈通常限制为 256k。
Stack variables (often called 'automatic variables') is best used for things you want to always be the same, and always be small.
Are all stack allocations, These are fixed at compile time too.
The best reason for heap allocation is that you cant always know how much space you need. You often only know this once the program is running. You might have an idea of limits but you would only want to use the exact amount of space required.
If you had to read in a file that could be anything from 1k to 50mb, you would not do this:-
That would try to allocate 50mb on the stack, which would usually fail as the stack is usually limited to 256k anyway.
如果您使用整个内存段,堆栈和堆共享相同的“开放”内存空间,并且最终必须到达它们相遇的点。保持它们每个人使用的空间之间的平衡将在以后分配和取消分配内存时摊销成本较小的渐近值。
The stack and heap share the same "open" memory space and will have to eventually come to a point where they meet, if you use the entire segment of memory. Keeping the balance between the space that each of them use will have amortized cost later for allocation and de-allocation of memory a smaller asymptotic value.