alloca 在堆栈上分配内存

警告: 为了完整起见,此处仅提及 alloca。它完全不可移植(不受任何通用标准的保护),并且具有许多潜在危险的功能,使其不安全。现代 C 代码应该用可变长度数组 (VLA) 代替它。

手册页

#include <alloca.h>
// glibc version of stdlib.h include alloca.h by default

void foo(int size) {
    char *data = alloca(size);
    /*
      function body;
    */
    // data is automatically freed
}

在调用者的堆栈帧上分配内存,当调用者函数完成时,返回指针引用的空间将自动释放

虽然此功能便于自动内存管理,但请注意,请求大量分配可能导致堆栈溢出,并且你不能将 free 与分配了 alloca内存一起使用 (这可能会导致更多堆栈溢出问题)。

由于这些原因,不建议在循环内使用 alloca 也不建议使用递归函数。

并且因为在函数返回时内存是 free’d ,你不能将指针作为函数结果返回( 行为将是未定义的 )。

摘要

  • 呼叫与 malloc 相同
  • 功能返回时自动释放
  • freerealloc 函数不兼容 ( 未定义的行为
  • 指针不能作为函数结果返回( 未定义的行为
  • 堆栈空间限制的分配大小,(在大多数机器上)比 malloc() 可用的堆空间小很多
  • 避免在单个函数中使用 alloca() 和 VLA(可变长度数组)
  • alloca() 不像 malloc() 等人那样便携

建议

  • 不要在新代码中使用 alloca()

Version >= C99

现代替代品。

void foo(int size) {
    char data[size];
    /*
      function body;
    */
    // data is automatically freed
}

这适用于 alloca(),并且在 alloca() 没有的地方工作(例如在内部循环中)。它确实假定 C99 实现或未定义 __STDC_NO_VLA__ 的 C11 实现。