0

函数_alloca(alloca)在栈上分配内存,不需要“free”。

是否可以在 C 中编写一个在堆栈上分配的函数?

另一种表达方式:_alloca 做到了!

或者这在 C 中是不可能的,因为其他原因包括:1)功能是用 ASM 编写的 2)它是 C 运行时库的一个特性。

我对编写类似 alloca 的函数感兴趣的原因如下:

void func (const char *path, const char* filename)
{
   char s[1024];
   snprintf (s, sizeof(s), "%s/%s", path, filename);
}

但我更喜欢:

void func (const char *path, const char* filename)
{
   char *s = alloca_sprintf ("%s/%s", path, filename);

// ... No need to free.
}

在此先感谢任何了解该主题的人。asnprintf 是对使用固定大小缓冲区的改进,但仍需要清理。

4

4 回答 4

2

如果您的目标只是最小化消耗的堆栈空间,那么您只需要 C99 VLA:

void func (const char *path, const char *filename)
{
   char s[strlen(path) + strlen(filename) + 2]; // +2 for '/' and null terminator
   sprintf(s, "%s/%s", path, filename);
   ...
}

这与您获得的功能相同alloca,而且是标准的!

于 2013-06-12T02:59:53.180 回答
0

我相信这应该是可能的,但这取决于您的工具链(特别是编译器如何使用堆栈)和您的处理器架构 - 基本上,编译器可能需要知道哪些变量的相对位置可能会改变(对于放置在堆栈,因为堆栈的顶部会改变 - 仅适用于堆栈上的变量,因为编译器可能会将一些变量完全放在寄存器中)。

因此,我希望像 _alloca() 这样的函数的任何现有实现都与运行时库所属的编译器(和体系结构)的特定版本相关联。自己实现可能不容易,也可能不容易实现,但它可能不是很便携,除非您能够使用一些技巧(可能使用 C++ 模板?)。

于 2013-06-12T02:58:30.213 回答
0

您的建议是堆栈上的内存分配发生在函数 alloca_sprintf() 中,然后返回它。问题是,当函数 alloca_sprintf() 返回时,内存分配将消失——因为它的堆栈一返回就崩溃了。内存将是无效的。

于 2013-06-12T03:06:07.427 回答
0

作为一个函数做alloca基本上是不可能的,因为alloca存储生命周期的语义是在函数返回时结束。alloca一些编译器提供的不是函数而是内置函数。如果可以使用使用的alloca来实现您想要的,但总的来说,alloca这是一个非常糟糕的主意。没有办法alloca报告失败;如果您尝试分配太多,它只会默默地破坏不相关的数据和/或崩溃。

于 2013-06-12T03:29:41.737 回答