这实际上与我昨天问的问题有关,为什么今天使用的应用程序同时需要堆栈和堆(以及为什么不能只使用堆而不同时使用堆,为了拥有简单的&唯一标准)。
但是,许多响应表明堆栈是不可替代的,这是因为与尝试分配/引用堆相比要快数百(或数千)倍。我知道,如果不使用Heap,动态存储分配就会出现问题,但是没有办法解决这一问题,或者没有办法在Stack上进行改进以使其能够处理动态内存分配吗?
这实际上与我昨天问的问题有关,为什么今天使用的应用程序同时需要堆栈和堆(以及为什么不能只使用堆而不同时使用堆,为了拥有简单的&唯一标准)。
但是,许多响应表明堆栈是不可替代的,这是因为与尝试分配/引用堆相比要快数百(或数千)倍。我知道,如果不使用Heap,动态存储分配就会出现问题,但是没有办法解决这一问题,或者没有办法在Stack上进行改进以使其能够处理动态内存分配吗?
Answers:
堆栈的问题在于,除非内存位于堆栈顶部,否则您无法“释放”内存。例如,假设您分配了3种大小不同的东西:
a = allocate(2000000); // 2000000 bytes
b = allocate(1);
c = allocate(5000000);
堆栈将a
在底部,b
中间和c
顶部。如果我们要免费,这将成为问题b
:
free(b); // b is not on top! We have to wait until c is freed!
解决方法是先移动所有数据,b
然后再移动a
。这可行,但是在这种情况下将需要500万个副本-这比堆慢得多。
这就是为什么我们有一个堆。尽管分配的速度可能比堆栈慢(O(log n)
vs O(1)
),但与堆栈的内存O(log n)
相比,堆可以更快地释放任意位置的内存-O(n)
Facebook doesn't remove content from its disk when you ask it to remove it, it just removes the pointer to it
-本质上就是在任何操作系统上普通删除文件时发生的情况。
堆栈是一种LIFO(后进先出)结构,其顶部保留了一个引用指针(通常由硬件支持)。话虽如此,您要尝试在堆栈而不是堆上分配的任何内容都必须是每个函数的局部变量,位于该堆栈的顶部。因此,反对栈的主要原因是您的main()例程需要预先分配程序使用的所有数据结构(打算在程序的整个过程中使用)作为分配的所有数据结构当这些函数调用返回并且其框架或激活记录从堆栈中弹出时,这些函数调用内的函数最终将被删除。
堆栈对于遵循后进先出(LIFO)规则的内存分配非常有用,也就是说,您可以按照分配的完全相反的顺序释放内存。LIFO是一种非常常见的,也许是最常见的内存分配模式。但这不是唯一的模式,甚至不是唯一的通用模式。为了编写可以解决各种问题的高效程序,我们必须考虑到不太常见的模式,即使这意味着更复杂的基础结构也是如此。
如果我能获得段落的所有元数据:您是一个初学者,作为一个初学者,您重视简单性和黑白规则。但是,作为初学者,您只能窥视计算机程序必须解决的一系列问题和约束。您正在进入一项经过75年积极开发的技术。询问为什么事情是这样并没有错,但是答案通常是:“是的,我们在50年前尝试了简单,直接的方法,结果证明整个课程的效果都不理想问题,所以我们不得不做一些更复杂的事情”。随着技术的进步,简单性通常必须让位于效率和灵活性。