这本质上是我的问题。在函数的生命周期中,我生成一些整数,然后在算法中使用整数数组,该算法也是同一函数的一部分。整数数组只能在函数中使用,因此将数组存储在堆栈中自然是有意义的。
问题是,在我完成所有整数生成之前,我不知道数组的大小。
我知道如何在堆栈上分配固定大小和可变大小的数组。但是,我不知道如何在堆栈上生成数组,这似乎是解决我的问题的最佳方法。我相当确定这可以在汇编中完成,只需增加堆栈指针并为生成的每个int存储一个int,因此int数组将位于堆栈帧的末尾。这可能在C中做到了吗?
答案 0 :(得分:8)
我不同意你的断言"所以很自然地将数组存储在堆栈上#34;。堆栈内存实际上是为您在编译时知道大小而设计的。我认为动态记忆是去这里的方式
答案 1 :(得分:4)
C没有定义"堆栈"是。它只有静态,自动和动态分配。静态和自动分配由编译器处理,只有动态分配才能将控件放在您的手中。因此,如果要手动取消分配对象并分配更大的对象,则必须使用动态分配。
答案 2 :(得分:2)
不要在堆栈上使用动态数组(比较Why is the use of alloca() not considered good practice?),使用malloc
更好地从堆中分配内存,并使用realloc
调整其大小。
答案 3 :(得分:1)
绝不使用alloca()
恕我直言,这一点在标准参考文献中还不够好。
一条经验法则是:
如果您不准备将最大可能大小静态分配为 固定长度的C数组然后你不应该用
alloca()
动态地执行它。
为什么呢?您试图避免malloc()
的原因是性能。
alloca()
将会变慢并且在任何情况下都无法正常工作,静态分配将失败。它的成功率通常不如malloc()
。
有一件事是肯定的。静态分配最大值将超过malloc()
和alloca()
。
静态分配通常在无操作附近。无论如何,大多数系统都会提升函数调用的堆栈指针。多远没有明显差异。
所以你告诉我的是你关心性能但是想要阻止无操作解决方案?想想你为什么这么想。
压倒性的可能性是你担心分配的大小。
但正如所解释的那样它是免费的,它会被收回。有什么担心的?
如果担心的是“我没有最大值或者不知道它是否会溢出堆栈”那么你不应该使用alloca()
,因为你没有最大值并知道它是否会溢出堆栈。
如果你确实有一个最大值并且知道它不会打击堆栈然后静态分配最大值并回家。这是免费的午餐 - 还记得吗?
这使alloca()
错误或次优。
每当你使用alloca()
时,你要么浪费你的时间,要么在难以测试的任何一个任意缩放天花板中进行编码,这些天花板会安静地睡觉,直到事情变得非常重要,然后才能开始某人的某一天
别。
PS:如果你需要一个大的“工作空间”,但是malloc()
/ free()
开销是一个瓶颈,例如在一个大循环中反复调用,那么考虑一下在循环外部分配工作空间并将其从迭代传递到迭代。如果您发现“大”案例,则可能需要重新分配工作区,但通常可以将分配数除以100甚至1000。
<强>脚注:强>
必须有一些理论算法,其中a()调用b(),如果a()需要大规模环境,b()不会,反之亦然。
在那种情况下,alloca()
阻止了堆栈溢出,可能会出现某种怪异的游戏。我从未听说过或见过这样的算法。我们将非常感谢合理的标本!
答案 4 :(得分:0)
为了解决您的问题,动态内存分配看起来很理想。
int *a = malloc(sizeof(int));
并取消引用它来存储值。 每次需要将新整数添加到现有的整数列表
时int *temp = realloc(a,sizeof(int) * (n+1)); /* n = number of new elements */
if(temp != NULL)
a = temp;
使用此内存free()
完成后。
答案 5 :(得分:0)
C编译器的内部要求在编译时修复或计算堆栈大小。我用了C(现在是C ++转换器)已经有一段时间了,我不知道为什么会这样。 http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html提供了两种方法的利弊的有用比较。
我很欣赏您的汇编代码类比,但是如果操作系统有任何意义,那么C主要是通过操作系统进行管理,它会强制/提供任务,进程和堆栈符号。