函数_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比使用固定大小的缓冲区有所改进,但仍需要清理。
答案 0 :(得分: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
获得的功能相同,而且是标准的!
答案 1 :(得分:0)
我认为它应该是可能的,但它取决于你的工具链(具体来说,编译器如何使用堆栈)和你的处理器架构 - 基本上,编译器可能需要知道哪些变量的相对位置可能会改变(对于变量而言)放在堆栈上,因为堆栈的顶部会发生变化 - 仅适用于堆栈上的变量,因为编译器可能会将一些变量完全放在寄存器中。)
因此,我希望像_alloca()这样的函数的任何现有实现都绑定到运行时库所属的编译器(和体系结构)的特定版本。它可能也可能不容易实现,但它可能不是非常便携,除非你能够使用一些技巧(可能使用C ++模板?)。
答案 2 :(得分:0)
你的建议是堆栈上的内存分配发生在alloca_sprintf()函数中,然后返回它。问题是,当函数alloca_sprintf()返回时,内存分配将会消失 - 因为它的堆栈会在返回时立即崩溃。记忆无效。
答案 3 :(得分:0)
将alloca
作为函数从根本上讲是不可能的,因为alloca
的语义是指存储生命周期在函数返回时结束。某些编译器提供的alloca
不是一个函数,而是一个内置函数。如果可以通过使用alloca
的宏实现您想要的效果,但通常情况下,alloca
是一个非常糟糕的主意。 alloca
无法报告失败;如果你试图分配太多,它只会默默地破坏不相关的数据和/或崩溃。