【问题标题】:Is it possible to write an _alloca-like function in C?是否可以在 C 中编写类似 _alloca 的函数?
【发布时间】:2013-06-08 01:30:36
【问题描述】:

函数_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 是对使用固定大小缓冲区的改进,但仍需要清理。

【问题讨论】:

标签: c stack alloca


【解决方案1】:

如果您的目标只是最小化消耗的堆栈空间,那么您只需要 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 获得的功能相同,而且是标准功能!

【讨论】:

  • 糟糕。对于那个很抱歉。我想我们的头和手指之间有一秒钟的比赛条件:)
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 谁能说alloca_sprintf 不能在编译器帮助下实现为宏或(如alloca)?
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-20
      • 2012-01-24
      • 2020-06-20
      相关资源
      最近更新 更多