gpt4 book ai didi

C++ 可变参数和 vsprintf

转载 作者:行者123 更新时间:2023-11-30 02:04:05 30 4
gpt4 key购买 nike

我正在尝试为 cstdio 中的标准 sprintf 函数编写一些包装器。但是,我在运行我的程序时遇到了一些奇怪的行为和访问冲突崩溃。我简化了问题并在下面的代码中重现了它:

#include <string>
#include <cstdio>
#include <cstdarg>

std::string vfmt(const std::string& format, va_list args)
{
int size = format.size() * 2;
char* buffer = new char[size];
while (vsprintf(buffer, format.c_str(), args) < 0)
{
delete[] buffer;
size *= 2;
buffer = new char[size];
}

return std::string(buffer);
}

std::string fmt(const std::string& format, ...)
{
va_list args;
va_start(args, format);
std::string res = vfmt(format, args);
va_end(args);
return res;
}

int main()
{
std::string s = fmt("Hello %s!", "world");
printf(s.c_str());
return 0;
}

vfmt 中调用 vsprintf 时,此代码会产生内存访问冲突。但是,当我将 fmt 的函数签名从 fmt(const std::string& format, ...) 更改为 fmt(const char* format, . ..),我不再崩溃,一切都按预期进行。为什么会发生这种情况?

为什么将 format 参数的类型从 const std::string& 更改为 const char* 可以解决问题?或者它只是看起来已经解决了?

最佳答案

您不能将引用类型用作 va_start 的参数。这就是为什么更改为 char* 会起作用,因此会保留 string 但没有 &。使用引用会破坏为获取可变数量的参数而完成的魔法。

参见 Are there gotchas using varargs with reference parameters .

关于C++ 可变参数和 vsprintf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11088754/

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