gpt4 book ai didi

C++ 标准参数 : multiple calls to va_start

转载 作者:太空狗 更新时间:2023-10-29 23:36:58 27 4
gpt4 key购买 nike

我注意到在两个函数中连续调用时 va_start 有一些问题。下面是一个基本示例:

std::string format(std::string fmt, ...)
{
char buf[2000];
va_list aq;
va_start(aq, fmt);
vsprintf(buf, fmt.c_str(), aq);
va_end(aq);
return std::string(buf);
}
void error(std::string fmt, ...)
{
va_list ap;
va_start(ap, fmt);
printf("%s", format(fmt, ap).c_str());
va_end(ap);
exit(1);
}

int main()
{
int x = 10;
printf("%s", format("Test %d\n", x).c_str());
error("Test %d\n", x);
}

产生

Test 10
Test -1078340156

看来,在使用 error 函数时,参数已损坏。

va_list 传递给另一个函数的正确方法是什么?

最佳答案

您可以将 va_list 作为参数显式传递。将 va_list 传递给采用多个参数的函数不会“解压”这些参数。相反,它只是调用带有两个参数的函数,第二个参数是 va_list。您从函数中获取垃圾的原因是它试图将 va_list 解释为 printf 的参数之一,从而导致未定义的行为。

这就是为什么有像 vsprintf 这样的函数的原因 - 这样像 printfsprintf 这样的函数可以在内部调用辅助函数来完成格式化,给定参数的 va_list

例如:

std::string vformat(std::string fmt, va_list args) {
char buf[2000];
vsprintf(buf, fmt.c_str(), args);
return std::string(buf);
}

void error(std::string fmt, ...) {
va_list ap;
va_start(ap, fmt);
printf("%s", vformat(fmt, ap).c_str());
va_end(ap);
exit(1);
}

尽管如此,在 C++ 中您应该使用可变参数模板来执行此操作,因为它们可以正确转发,完全类型安全,并且(如果您正确实现)不会冒缓冲区溢出的风险。

p>

希望这对您有所帮助!

关于C++ 标准参数 : multiple calls to va_start,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11043986/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com