使用堆栈以避免动态分配是不好的方式吗?
我明白这个非常类似的问题给出了答案: 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被大量调用,在堆中保留内存会花费更多时间,并且这会对性能产生影响吗?
会有什么理由使用第二种方法吗?
在栈上分配的问题(或)堆是依赖于以下参数:
要在其中变量可用范围和续航时间:说,在你的计划,如果你需要使用
main
中的test_alloc
之后的double数组成员,你应该去动态分配。您的堆栈的大小:假设你正在使用的
test_alloc
功能,其中有4K堆栈线程的上下文,您的数组大小这又依赖于size
变量账户1K,那么堆栈分配是不可取的,你应该去动态分配。复杂的代码:当使用动态分配,enusre照顾避免内存泄漏,悬摆指针等的这增加了复杂性的一些量的代码和更容易错误。
分配的频率:在一个循环中调用
malloc
和free
可以具有较小的性能。这一点是基于这样一个事实,即堆栈分配仅仅是取消SP
的事情,相反,堆中的分配需要更多的记录。
感谢您的答案。但是,你是否会对“从不兼容的指针类型更新参数1”发出警告进行解释? – Vince
因为'p'是一个双精度数组,所以调用update函数作为'update(p,size)'。这是因为当你通过名称引用数组时,它会衰减到数组中第一个元素的指针,在这种情况下它将是一个'double *'。 –
在堆栈版本中,您不能分配具有100000000个元素的数组。当使用堆栈分配小数组时,速度更快。当分配非常大的数组时,使用堆。
约栈,堆内存分配的更多信息,请考虑以下文字: Stack-based memory allocation,Heap-based memory allocation
“如果test_alloc被大量调用,是它更耗时堆中保留内存,可能这有任何影响性能?”
嗯,我想你正在从堆栈和堆分配性能。总是堆栈分配速度更快,因为它只是移动堆栈指针。堆分配肯定需要更多时间,因为它必须执行内存管理。所以如果你在上述函数中没有太多的操作不会导致堆栈溢出(因为在堆栈上创建太多的对象会增加堆栈溢出的机会),并且你不需要这个变量的作用域就可以可能使用堆栈本身。
所以要回答你的问题,如果你没有在堆栈上使用太多的对象并导致堆栈溢出,那么使用堆栈来避免动态分配并不坏。
希望这会有所帮助。
当需要传递数据时,请使用堆,否则堆栈,就像链接中的帖子回复一样。在你的例子中,不需要使用堆,但是当程序变得更大时,你将需要将数据存储在堆中,因为它可以在任何地方传播。 – moeCake
你自己给出了答案。 – user3007735
是这样做的,但是让我怀疑的是一个警告:“从不兼容的指针类型更新参数1”。其实,应该在帖子中写下。 – Vince