为什么使用alloca()不被认为是好的做法?

alloca()从堆栈中分配内存,而不是malloc()堆。 所以,当我从例程返回时,内存被释放。 所以,实际上这解决了我释放动态分配内存的问题。 释放通过malloc()分配的内存是一个非常头痛的问题,如果不知何故错过了会导致各种内存问题。

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


答案就在man页(至少在Linux上):

返回值alloca()函数返回一个指向分配空间开始的指针。 如果分配导致堆栈溢出,则程序行为未定义。

这并不是说它永远不会被使用。 我工作的OSS项目之一广泛使用它,只要你不滥用( alloca巨大的价值),就没有问题。 一旦你过去了“几百字节”的标记,现在是时候使用malloc和朋友了。 你仍然可能会得到分配失败,但至少你会有一些失败的迹象,而不是把堆栈炸掉。


我遇到的最难忘的错误之一是使用alloca的内联函数。 它在程序执行的随机点表现为堆栈溢出(因为它在堆栈上分配)。

在头文件中:

void DoSomething() {
   wchar_t* pStr = alloca(100);
   //......
}

在实现文件中:

void Process() {
   for (i = 0; i < 1000000; i++) {
     DoSomething();
   }
}

所以发生了什么事情是编译器内嵌了DoSomething函数,并且所有的堆栈分配都发生在Process()函数内部,从而使堆栈上升。 在我的辩护(我不是那个发现这个问题的人,当我不能修复它时,我不得不去找一个高级开发人员哭),这不是直接的alloca ,它是ATL字符串之一转换宏。

所以课程是 - 不要在你认为可能被内联的函数中使用alloca


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

char arr[size];

代替

char *arr=alloca(size);

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

链接地址: http://www.djcxy.com/p/79837.html

上一篇: Why is the use of alloca() not considered good practice?

下一篇: What is the range of an address on stack and memory?