我一直认为需要堆分配来分配编译时未知的大小的数据结构。但我最近了解了alloca
,它允许在堆栈上进行动态分配。因此,如果动态大小的分配不需要堆分配,是否需要堆分配?我的第一个想法是调整数据结构的大小可能很困难,但我不确定如果不使用堆就不可能。
答案 0 :(得分:1)
如果您限制自己使用堆栈作为内存,那么您可以将数据的生命周期限制为它们所构建范围的生命周期。是的,您可以将它们设置为全局但是您的数据具有固定的内存量
我们如何保留大量的全局内存?那么现在你只是在内存浪费的情况下模拟堆。
答案 1 :(得分:1)
这是关于实时的。堆上的对象一直存在,直到你free()
为止。分配有alloca
的对象存在于当前堆栈帧中,直到函数返回。
如果第一次分配没有保留足够的内存,则调整堆上数据的大小将导致新的分配。这将使第一个堆项返回空闲列表。这在堆栈框架中是不可能的。没有realloc
吊坠。
顺便说一句:堆上的对象不需要动态大小。 malloc
的函数签名采用大小参数,允许您在运行时计算大小。但是你经常在没有动态大小的情况下分配对象e.g。
typedef struct {
int a;
char s[3];
} example;
example *ex = malloc(sizeof(example));
free(ex);
编辑:虽然您可以在堆栈上反复分配,除非您获得堆栈溢出,但语义与realloc
不同。当realloca
应该为更大的尺寸分配时,不可能返回空间。缩小尺寸甚至是不可能的。两者的原因是alloca
如何运作的机制。没有空闲列表,并且堆栈中没有像堆对象一样进行管理的块。它只是改变了堆栈指针,为alloca
的结果提供了空间。
答案 2 :(得分:0)
没有必要使用堆,double
不是必需的,int
不是必需的,只需要0
和1
以及Turning Machine。
存在不同的编程模型来有效地创建和维护代码。代码可能与堆栈中的所有内容一起存在。根据操作系统/环境的设置方式,堆栈的运行速度不会快于堆。内存是内存 - 只是典型的操作系统对堆栈大小施加了更严格的限制,因为更需要大堆栈的代码错误而不是正确。
处理器往往也是这样设计的,允许大而有限的堆栈,以及相对庞大的动态数据空间。
所以现在,通过malloc()
执行大多数可变大尺寸分配,并保存alloca()
用于小众应用。也许在20年内,由于Whippersnapper博士最新的编程模型,所有东西都将在堆栈中。