我写了一个非常简单的测试代码来测试vsnprintf,但是在xcode和visual studio环境下,结果却大不相同,测试代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <cstdarg>
void p(const char* fmt, ...)
{
static const int DefaultLength = 256;
char defaultBuf[DefaultLength] = { 0 };
va_list args;
va_start(args, fmt);
vsprintf(defaultBuf, fmt, args);
printf("%s\n", defaultBuf);
memset(defaultBuf, 0, sizeof(defaultBuf));
vsnprintf(defaultBuf, DefaultLength, fmt, args);
printf("%s\n", defaultBuf);
va_end(args);
}
int main(int argc, const char* argv[])
{
// if you uncomment this line(std::cout ...), it will crash at vsnprintf in xcode
std::cout << "Tests...!\n";
p("Create:%s(%d)", "I'm A String", 0x16);
return 0;
}
这是Visual Studio中的输出:
Tests...!
Create:I'm A String(22)
Create:I'm A String(22)
这是正常的,似乎不是问题。但同样的代码,我创建了一个macos命令行项目,将这段代码粘贴进去,奇怪的事情发生了,当代码执行到vsnprintf时,它会直接启动EXC_BAD_ACCESS。
更离谱的是,如果我注解掉main函数中的std::cout,它不会崩溃,但输出是错误的。所以问题是,造成这种差异的原因是什么,这些函数不都应该是C标准库的函数,它们的行为应该受到标准库的约束吗?还是我的用法错误?当我删除std::cout时的输出:
Create:I'm A String(22)
Create:\310\366\357\277\367(3112398)
Program ended with exit code: 0
如果只有一个是对的,是xcode对还是visual studio对,最后我用的是最新的xcode 14,visual studio 2022。
2条答案
按热度按时间yb3bgrhw1#
您必须在呼叫
vsprintf
之间重新初始化va_list
。若未执行此作业,则为未定义的行为。请参阅https://en.cppreference.com/w/c/variadic/va_list:
如果创建了一个
va_list
示例,并将其传递给另一个函数,然后在该函数中通过va_arg使用该示例,则在调用函数中的任何后续使用之前都应调用va_end
。rks48beu2#