使用堆栈避免动态分配是一种糟糕的方式吗?

时间:2013-12-13 09:42:07

标签: c memory-management stack heap

我理解这个非常相似的问题所给出的答案: 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,那么在堆中保留内存会更耗时吗?这会对性能产生影响吗?

有没有理由使用第二种方法?

3 个答案:

答案 0 :(得分:4)

堆栈(或)堆中的分配问题取决于以下参数:

  • 您希望变量可用的范围和生命周期:如果您需要在test_alloc之后使用double数组的成员,请在您的程序中说main,您应该进行动态分配。

  • 堆栈的大小:假设您在具有 4K 堆栈的线程的上下文中使用test_alloc函数,而你的数组大小依赖于size变量帐户 1K ,那么不建议进行堆栈分配,你应该进行动态分配。

  • 代码的复杂性:使用动态分配时,请注意避免内存泄漏,悬空指针等。这会增加代码的复杂性并且更容易出错

  • 分配频率:在循环中调用mallocfree可能会降低性能。这一点基于这样的事实:堆栈中的分配只是偏离SP的事实,相反,堆中的分配需要更多的簿记。

答案 1 :(得分:1)

在堆栈版本中,您无法分配具有100000000元素的数组。使用堆栈分配小数组时,速度更快。当使用堆分配非常大的数组时。

有关堆栈,堆内存分配的更多信息,请考虑以下内容: Stack-based memory allocationHeap-based memory allocation

答案 2 :(得分:1)

“如果大规模调用test_alloc,那么在堆中保留内存会更耗时吗?这会对性能产生影响吗?”

嗯,我想你正在研究从堆栈和堆分配的性能。总是堆栈分配更快,因为它只是移动堆栈指针。堆分配肯定需要更多时间,因为它必须进行内存管理。所以如果你在上面说的函数中没有太多的操作,这不会导致堆栈溢出(因为在堆栈上创建太多的对象会增加堆栈溢出的机会)并且如果你不需要这个变量的范围,你可以可能使用堆栈本身。

所以要回答你的问题,如果你不在堆栈上使用太多的对象并导致堆栈溢出,那么使用堆栈来避免动态分配并不是一种糟糕的方式。

希望这有帮助。