使用 C99 VLA 是个好主意吗?与 malloc/free 相比,何时使用 VLA 更合适?(因为 VLA 可能会炸毁堆栈?)
6 回答
是的,除非你知道你的堆栈会爆炸。如有必要,您还可以更改堆栈的大小,每个操作系统的方式都不同,但这是可能的。VLA 的优点是:
快速:无论如何都会调整堆栈指针和/或帧指针,因此 VLA 的成本几乎为 0。
Easy :一个简单的定义,没有初始化指针,检查释放并且没有内存泄漏的风险。
它是自动线程安全的,因为每个线程都有自己的堆栈。它还具有更好的扩展性,因为不需要锁定,这是使用
malloc/free
.可读性:这确实是一个简单的概念,因此不太可能引入细微的错误。
它有一些缺点:
大小有限:如前所述,堆栈可能会爆炸。
缓冲区溢出比堆内存要严重一些(可以说这是一种优势,因为崩溃的应用程序比一个默默地破坏数据并最终在不相关的指令上崩溃的应用程序更好)。
可移植性:并非所有编译器都实现它,但它通常可以被模拟
alloca
(注意语义有点不同,但没有什么真正严重的)。
堆栈分配的主要优点是您可以获得分配的可变长度数组的自动内存管理。由于内存管理是任何 C 程序的核心挑战之一,如果可以的话,您绝对应该使用 VLA 来简化您的任务。
然后,我将主张您应该尽可能一致地使用 VLA,否则仅在以下情况下使用 malloc:您需要控制存储的持续时间,如果您有非常大的分配,并且如果您想处理内存不足优雅地错误。
只是添加另一个方面(不是直接答案,因为不涉及 malloc/free,但仍然相关):
//
// File: someheader.h
//
// Description: Some header intended to be usable in C a n d C++.
// (skipping include guards only for brevity!)
//
#ifdef __cplusplus
extern "C"
{
#endif
void f(size_t n, int(*)[n]); // OOPS: not supported by C++...
#ifdef __cplusplus
}
#endif
所以这不仅仅是因为移植,而是一个更普遍的兼容性问题......
如果你需要这样的兼容性,你需要跳过 VLA。
C++ 不支持 VLA。因此,如果需要的话,将代码移植到 C++ 会稍微费点力气。
再说一次,有些人认为这实际上是一件好事,并狡猾地提出“类”作为 c 中符号的美妙名称 :-)
有关 C99 相关链接的良好列表(包括指向有关可变长度数组的信息的链接),请参阅:
Xcode 现在默认使用 C99 - 那么 C99 是什么?
http://lists.apple.com/archives/xcode-users/2008/May/msg00665.html
如果您的项目仅使用符合 C99 的编译器进行编译,并且替代方法是使用 alloca(),则使用 C99 VLA 是一个好主意。VLA 不应该用在你通常使用 malloc() 的地方,如果你不知道 alloca() 的作用以及你可能遇到的问题,你不应该使用 VLA。