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

hivapdat  于 2022-11-17  发布在  其他
关注(0)|答案(2)|浏览(140)

我写了一个非常简单的测试代码来测试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。

yb3bgrhw

yb3bgrhw1#

您必须在呼叫vsprintf之间重新初始化va_list。若未执行此作业,则为未定义的行为。
请参阅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);
}
rks48beu

rks48beu2#

void p(const char* fmt, ...)
{
    static const int DefaultLength = 256;
    char defaultBuf[DefaultLength] = { 0 };
    
    va_list args;
    va_start(args, fmt);
    
    va_list args_r;
    va_copy(args_r, args);
    
    vsprintf(defaultBuf, fmt, args);
    printf("%s\n", defaultBuf);
    
    memset(defaultBuf, 0, sizeof(defaultBuf));
    vsnprintf(defaultBuf, DefaultLength, fmt, args_r);
    printf("%s\n", defaultBuf);
    va_end(args_r);
    va_end(args);
}

相关问题