C函数中的变量参数

时间:2017-05-20 10:41:29

标签: c stack heap

我已经阅读了关于变量参数函数" int func(int, ...)"。 这些函数的参数在哪里被分配(堆栈或堆)?

因为我读到va_end()宏释放了分配给va_list的空间,所以单词"释放"引起了我的注意。

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

我只是想知道它不像没有预先定义空间的数组; 我们最后使用malloc()free()

链接:https://www.tutorialspoint.com/cprogramming/c_variable_arguments.htm

2 个答案:

答案 0 :(得分:2)

本身没有指定“堆”或“堆栈”之类的东西,因此编程标准和可移植的,你应该更好地考虑标准的类别:静态,自动和动态存储。

然而,在典型的实现中,“自动存储”转换为“堆栈用于它”。这是函数参数的情况,可变参数函数在这里也不例外。

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

请注意,va_start()的实现没有来分配内存。 va_list可能以某种方式定义,它为所需的上下文信息提供空间。但是作为程序员,你应该根本不感兴趣,所有va_*内容都是黑盒子,如果文档说明“call完成清理时va_end()“,你就这样做了;)

答案 1 :(得分:0)

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

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

另请注意,实际上变量args列表用于包装对vsprintf()的调用。你几乎从未发现它们在生产C代码中用于任何其他目的。