Alloca()在堆栈上分配内存,而不是像malloc()那样在堆上分配内存。因此,当我从例程返回时,内存被释放。这实际上解决了动态分配内存的问题。通过malloc()释放分配的内存是一个非常令人头痛的问题,如果以某种方式错过释放会导致各种内存问题。

尽管有上述特性,为什么不鼓励使用alloca() ?


当前回答

其他答案都是正确的。但是,如果使用alloca()要分配的对象相当小,我认为这是一种比使用malloc()或其他方法更快、更方便的好技术。

换句话说,alloca(0x00ffffff)是危险的,可能会导致溢出,就像char hugeArray[0x00ffffff];是多少。小心谨慎,通情达理,你会没事的。

其他回答

每个人都已经指出了堆栈溢出潜在的未定义行为,但我应该提到的是,Windows环境有一个很好的机制来捕捉这种情况,使用结构化异常(SEH)和保护页面。由于堆栈只在需要时增长,因此这些保护页驻留在未分配的区域。如果你对它们进行分配(通过溢出堆栈),就会抛出一个异常。

您可以捕获这个SEH异常并调用_resetstkoflw来重置堆栈并继续您的快乐之路。这并不理想,但这是另一种机制,至少可以在事情发生时知道哪里出了问题。*nix可能有类似的东西,但我不知道。

我建议通过包装alloca并在内部跟踪它来限制您的最大分配大小。如果你真的很认真,你可以在函数的顶部设置一些作用域哨兵来跟踪函数作用域中的任何分配,并检查它与项目允许的最大数量是否一致。

此外,除了不允许内存泄漏之外,alloca也不会导致内存碎片,这是非常重要的。我不认为alloca是不好的做法,如果你明智地使用它,这基本上适用于所有事情。: -)

这里的大多数回答都忽略了一点:使用_alloca()可能比仅仅在堆栈中存储大对象更糟糕,这是有原因的。

自动存储和_alloca()之间的主要区别是,后者有一个额外的(严重的)问题:分配的块不受编译器控制,因此编译器无法优化或回收它。

比较:

while (condition) {
    char buffer[0x100]; // Chill.
    /* ... */
}

:

while (condition) {
    char* buffer = _alloca(0x100); // Bad!
    /* ... */
}

后者的问题应该是显而易见的。

老问题了,但是没有人提到它应该被可变长度数组取代。

char arr[size];

而不是

char *arr=alloca(size);

它存在于标准C99中,并作为编译器扩展存在于许多编译器中。

我想没有人提到过这一点:在函数中使用alloca会阻碍或禁用一些本来可以应用在函数中的优化,因为编译器无法知道函数的堆栈帧的大小。

例如,C编译器常见的优化是在函数中消除帧指针的使用,而是相对于堆栈指针进行帧访问;所以还有一种通用寄存器。但如果在函数内部调用alloca,则sp和fp之间的差异对于函数的一部分是未知的,因此无法进行此优化。

考虑到alloca的使用很少,而且它作为标准函数的不光彩地位,编译器设计人员很可能会禁用任何可能导致alloca出现问题的优化,如果要使它与alloca一起工作需要付出更多的努力的话。

更新: 由于变长局部数组已经添加到C语言中,并且由于这些向编译器提出了与alloca非常相似的代码生成问题,我看到“使用的罕见性和阴暗状态”不适用于底层机制;但是我仍然怀疑使用alloca或VLA会损害使用它们的函数中的代码生成。我欢迎来自编译器设计人员的任何反馈。

A place where alloca() is especially dangerous than malloc() is the kernel - kernel of a typical operating system has a fixed sized stack space hard-coded into one of its header; it is not as flexible as the stack of an application. Making a call to alloca() with an unwarranted size may cause the kernel to crash. Certain compilers warn usage of alloca() (and even VLAs for that matter) under certain options that ought to be turned on while compiling a kernel code - here, it is better to allocate memory in the heap that is not fixed by a hard-coded limit.