【问题标题】:Variable arguments in C functionsC 函数中的变量参数
【发布时间】:2017-10-20 11:01:56
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 通常变量参数被压入堆栈,就像常规参数一样。您不必担心mallocfree
  • 我只是想确定它不像没有预定义空间的数组:数组总是有一个预定义的空间。
  • 它有什么不同?

标签: c heap-memory stack-memory


【解决方案1】:

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

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

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

请注意,va_start() 的实现没有分配内存。 va_list 的定义方式可能是为所需的上下文信息提供空间。但这对作为程序员的你根本不感兴趣,所有va_* 的东西对你来说都是一个黑匣子,如果文档声明“调用@987654331 @当清理完成时”,你就这样做;)

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 2012-08-14
      • 1970-01-01
      • 2011-06-01
      • 2020-10-28
      • 2017-01-23
      相关资源
      最近更新 更多