我理解这个非常相似的问题所给出的答案: When is it best to use the stack instead of the heap and vice versa?
但我想证实:
这是一个非常简单的程序:
void update_p(double * p, int size){
//do something to the values refered to by p
}
void test_alloc(int size){
double p[size];
unsigned int i;
for(i=0;i<size;i++)p[i]=(double)i;
update(&p,size);
for(i=0;i<size;i++)printf("%f\n",p[i]);
}
int main(){
test_alloc(5);
return 1;
}
和test_alloc的替代版本:
void test_alloc(int size){
double * p = calloc(sizeof(double),size);
unsigned int i;
for(i=0;i<size;i++)p[i]=(double)i;
update(p,size);
for(i=0;i<size;i++)printf("%f\n",p[i]);
free(p);
}
似乎两个版本都有效(?)。一个是使用堆栈,另一个是使用堆(?)。 两种方法都有效吗?他们的优势或问题是什么?
如果确实从test_alloc退出时不使用该数组,那么第一种方法是否优先,因为不需要内存管理(即忘记释放内存)?
如果大规模调用test_alloc,那么在堆中保留内存会更耗时吗?这会对性能产生影响吗?
有没有理由使用第二种方法?
答案 0 :(得分:4)
堆栈(或)堆中的分配问题取决于以下参数:
您希望变量可用的范围和生命周期:如果您需要在test_alloc
之后使用double数组的成员,请在您的程序中说main
,您应该进行动态分配。
堆栈的大小:假设您在具有 4K 堆栈的线程的上下文中使用test_alloc
函数,而你的数组大小依赖于size
变量帐户 1K ,那么不建议进行堆栈分配,你应该进行动态分配。
代码的复杂性:使用动态分配时,请注意避免内存泄漏,悬空指针等。这会增加代码的复杂性并且更容易出错
分配频率:在循环中调用malloc
和free
可能会降低性能。这一点基于这样的事实:堆栈中的分配只是偏离SP
的事实,相反,堆中的分配需要更多的簿记。
答案 1 :(得分:1)
在堆栈版本中,您无法分配具有100000000元素的数组。使用堆栈分配小数组时,速度更快。当使用堆分配非常大的数组时。
有关堆栈,堆内存分配的更多信息,请考虑以下内容: Stack-based memory allocation,Heap-based memory allocation
答案 2 :(得分:1)
“如果大规模调用test_alloc,那么在堆中保留内存会更耗时吗?这会对性能产生影响吗?”
嗯,我想你正在研究从堆栈和堆分配的性能。总是堆栈分配更快,因为它只是移动堆栈指针。堆分配肯定需要更多时间,因为它必须进行内存管理。所以如果你在上面说的函数中没有太多的操作,这不会导致堆栈溢出(因为在堆栈上创建太多的对象会增加堆栈溢出的机会)并且如果你不需要这个变量的范围,你可以可能使用堆栈本身。
所以要回答你的问题,如果你不在堆栈上使用太多的对象并导致堆栈溢出,那么使用堆栈来避免动态分配并不是一种糟糕的方式。
希望这有帮助。