C 函数中的变量参数

Variable arguments in C functions

我读过可变参数函数“int func(int, ...)”。 这些函数的参数在哪里分配(堆栈或堆)?

因为我读到 va_end() 宏释放了分配给 va_list 的 space,所以 "frees" 这个词引起了我的注意。

注意:我知道常规函数会进入堆栈,但这种类型的函数很有趣,因为参数的数量是未知的。

我只想确定它不像没有预定义的数组space; 我们在最后使用 malloc()free()

Link: https://www.tutorialspoint.com/cprogramming/c_variable_arguments.htm

itself doesn't specify things like "heap" or "stack", so programming standard and portable , you should better think in categories of the 标准:静态、自动和动态存储。

然而,在典型的实现中,"automatic storage" 转换为 "the stack is used for it"。函数参数就是这种情况,可变参数函数也不例外。

va_end() 可能会释放一些动态存储空间(通常:分配在堆上)的原因是 va_arg() 宏通常需要一些上下文信息来查找 next 参数。 va_start() 将为该信息(而不是参数本身)分配内存 并以某种方式对其进行初始化,以便第一个 va_arg() 调用 returns第一个可变参数。

请注意,va_start() 的实现 没有 分配内存。 va_list 的定义方式可能是为所需的上下文信息提供 space。但这对作为程序员的你来说 根本没有兴趣,所有 va_* 东西对你来说都是一个 黑匣子 如果文档说明 "call va_end() when done for cleanup",你就照做 ;)

一般平台都有调用约定。前几个参数进入寄存器,随后的进入堆栈。这对 C 代码本身是故意不透明的。 va_start 和 va_end 提供了调用约定的包装器,允许您按索引而不是名称按顺序访问参数。

请注意,您无法在运行时构建 va_args 块。这是 C 不允许你做的少数事情之一。您只能通过调用变量 args 函数来生成块。

另请注意,实际上变量参数列表用于包装对 vsprintf() 的调用。您几乎永远不会发现它们在生产 C 代码中用于任何其他目的。