记录va_list重复使用导致的crash

博主介绍:程序喵大人

背景

最近遇到了个奇怪的问题,同样的代码,在Windows 下正常运行,在iOS下必现crash。

异常代码如下:

cpp 复制代码
std::string StringPrintf(const char* format, ...)
{
    va_list ap;
    va_start(ap, format);
    char* buffer = nullptr;
    const size_t size = std::vsnprintf(nullptr, 0, format, ap) + 1;
    buffer = new char[size];
    std::vsnprintf(buffer, size, format, ap);
    va_end(ap);
    std::string result(buffer);
    delete[] buffer;
    return result;
}

经过分析定位后发现,这里重复使用了va_list并且在vsnprintf后还继续使用了ap,进而导致的crash。

通过查看文档:https://port70.net/\~nsz/c/c11/n1570.html#7.21.6.8

这里明确说明,arg在vsnprintf后,会变成不确定的状态。所以才有了在Windows上可以正常运行,在iOS上会异常退出的问题。

如何解决这个问题?

标准做法是使用va_copy复制一份va_list,如下:

cpp 复制代码
std::string StringPrintf(const char* format, ...)
{
    va_list ap, ap_copy;
    va_start(ap, format);
    va_copy(ap_copy, ap);
    const int32_t size = std::vsnprintf(nullptr, 0, format, ap) + 1;
    va_end(ap);

    if (size <= 0) {
        return "";
    }

    char* buffer = new char[size];
    std::vsnprintf(buffer, size, format, ap_copy);
    va_end(ap_copy);

    std::string result(buffer);
    delete[] buffer;
    return result;
}

以前都是直接使用的三方库StringPrintf,而没有自己实现。这也算是使用vsnprintf过程中遇到的一个小坑,在此分享记录一下。

码字不易,欢迎大家点赞,关注,评论,谢谢!

相关推荐
TMedical19 分钟前
MedPlanning 截骨模拟矫形功能
c++·图像处理·人工智能·qt·健康医疗
我是唐青枫25 分钟前
Kotlin Delegation 委托详解
开发语言·kotlin
qq_4069810330 分钟前
共享变量一 关于extern与const
开发语言·c++
FRing031 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
小嘉丶学长2 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
迪菲赫尔曼2 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
chari克里3 小时前
QT5.15.2 + msvc2022部署全流程说明(windows可联网环境)
开发语言·c++·qt
Hello.Reader3 小时前
tsrs 技术解析用 Rust 移植 TypeScript 7,类型检查还能怎样提速?
开发语言·rust·typescript
透明的玻璃杯3 小时前
VS2015+QT 多线程
开发语言·qt
码匠许师傅4 小时前
【C++三方组件】mbedTLS:面向嵌入式的轻量 TLS
开发语言·c++