xcode下的vsnprintf函数和其他平台的vsnprintf有什么区别吗?

Hik*_*ari 1 c c++ xcode printf visual-studio

我写了一个非常简单的测试代码来测试vsnprintf,但是在xcode和Visual Studio环境下,结果有很大不同。测试代码如下:

\n
#define  _CRT_SECURE_NO_WARNINGS\n#include <iostream>\n#include <string.h>\n#include <cstdarg>\n\n\nvoid p(const char* fmt, ...)\n{\n    static const int DefaultLength = 256;\n    char defaultBuf[DefaultLength] = { 0 };\n    \n    va_list args;\n    va_start(args, fmt);\n    \n    vsprintf(defaultBuf, fmt, args);\n    printf("%s\\n", defaultBuf);\n    \n    memset(defaultBuf, 0, sizeof(defaultBuf));\n    vsnprintf(defaultBuf, DefaultLength, fmt, args);\n    printf("%s\\n", defaultBuf);\n    va_end(args);\n}\n\nint main(int argc, const char* argv[])\n{\n    // if you uncomment this line(std::cout ...), it will crash at vsnprintf in xcode\n    std::cout << "Tests...!\\n";\n    \n    p("Create:%s(%d)", "I\'m A String", 0x16);\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是 Visual Studio 中的输出:

\n
Tests...!\nCreate:I\'m A String(22)\nCreate:I\'m A String(22)\n
Run Code Online (Sandbox Code Playgroud)\n

这是正常现象,似乎不是什么问题。但是同样的代码,我创建了一个macos命令行项目,将这段代码粘贴进去,奇怪的事情发生了,当代码执行到vsnprintf时,它会直接启动EXC_BAD_ACCESS。

\n

在此输入图像描述\n更离谱的是,如果我注释掉main函数中的std::cout,它不会崩溃,但输出是错误的。那么问题来了,造成这种差异的原因是什么,这些函数不应该都是C标准库的函数,它们的行为应该受到标准库的约束吗?还是我的用法错误?\n删除 std::cout 时的输出:

\n
Create:I\'m A String(22)\nCreate:\\310\\366\\357\\277\\367(3112398)\nProgram ended with exit code: 0\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

如果只有一个是对的,是xcode对还是Visual Studio对,最后我用的是最新的xcode 14,Visual Studio 2022\xe3\x80\x82

\n

pad*_*ddy 5

您必须重新初始化va_list对 的调用之间的关系vsprintf。不这样做是未定义的行为。

请参阅https://en.cppreference.com/w/c/variadic/va_list

如果va_list创建了一个实例,将其传递给另一个函数,并通过该函数中的 va_arg 使用,则调用函数中的任何后续使用都应先调用va_end.

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);
    va_end(args);

    printf("%s\n", defaultBuf);
    
    memset(defaultBuf, 0, sizeof(defaultBuf));
    va_start(args, fmt);
    vsnprintf(defaultBuf, DefaultLength, fmt, args);
    va_end(args);

    printf("%s\n", defaultBuf);
}
Run Code Online (Sandbox Code Playgroud)