什么时候,通过声明一个固定大小的数组,alloca()比在堆栈上分配内存更可取?
详细信息:
正如我们所知,alloca()是一个有争议的功能。如果不小心使用,则会导致堆栈溢出。明智地使用它,可以避免堆分配,从而从紧循环中减少几纳秒。在这个问题中,关于为什么alloca被认为是坏的,一些顶尖的答案提倡偶尔使用alloca。
另一种从堆栈分配的方法是简单地声明一个固定大小的数组。这个策略的一个例子可以在arena类中霍华德·辛纳特的堆栈分配器中找到。(该代码当然是C++,但这个概念仍然适用于C。)
使用alloca与固定大小的数组有什么折衷之处?如果有的话,什么时候一个明显比另一个更好?这仅仅是一个在每一种情况下都应该进行经验性测试的性能问题(当性能是一个关键目标,并且已经确定了一个热点时)?固定大小的数组比较悲观--它总是像我们愿意在堆栈上分配的那样分配--但是还不清楚这是好还是坏。
为了尽可能明确起见,下面是两个函数实现的简单示例,其中似乎有理由使用alloca或固定大小的数组:
#include <alloca.h>
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
void foo_alloca(const size_t mem_needed) {
printf("foo_alloca(%zu)\n", mem_needed);
char* mem;
bool used_malloc = false;
if (mem_needed <= 100)
mem = alloca(mem_needed);
else {
mem = malloc(mem_needed);
used_malloc = true;
}
assert(mem_needed != 0);
// imagine we do something interesting with mem here
mem[0] = 'a';
mem[1] = 'b';
mem[2] = 'c';
mem[3] = '\0';
puts(mem);
if (used_malloc)
free(mem);
}
void foo_fixed(const size_t mem_needed) {
printf("foo_fixed(%zu)\n", mem_needed);
char* mem;
char stack_mem[100];
bool used_malloc = false;
if (mem_needed <= 100)
mem = stack_mem;
else {
mem = malloc(mem_needed);
used_malloc = true;
}
assert(mem_needed != 0);
// imagine we do something interesting with mem here
mem[0] = 'a';
mem[1] = 'b';
mem[2] = 'c';
mem[3] = '\0';
puts(mem);
if (used_malloc)
free(mem);
}
int main()
{
foo_alloca(30);
foo_fixed(30);
foo_alloca(120);
foo_fixed(120);
}另一个非常类似于alloca的选项是VLA。据我所知,从alloca和VLA获得的内存本质上是相同的行为,所以这个问题也适用于VLA。如果这种理解是错误的,只管提出来。
发布于 2016-10-03 22:14:12
使用
alloca()与固定大小数组之间的权衡是什么?
alloca()不是一个标准的C库函数。固定大小数组是语言的一部分。alloc()可分析性可能/可能不存在。alloca()分配被禁止的内存空间。固定大小的数组倾向于过度分配。alloca(),只是这是C99标准的一部分,但在C11中只有可选。https://stackoverflow.com/questions/39839865
复制相似问题