C/C++ 通过C语言可变参数打印(正常参数、正常格式化,运行不确定时间后崩溃)

news/2025/2/14 7:15:34/

在 C/C++ 之中,有时会遇到一些疑难杂症,但大多数情况下不会触发它,但如果触发它导致崩溃,的确会让人心态很炸裂。

我们知道我们想要提供C语言接口的动态参数传递给其它C动态参数函数,会通过va_list 来转发调用,这个在C语言之中是不存在问题的,但是在 C++ 之中它可能存在一些问题,这是因为 C++ 语言之中函数的调用协议之间是不确定的。

它可能是__fastcall、__thiscall、__stdcall 这些,而C语言函数调用协议是 __cdecl,这就带来潜在的不确定风险性。

即这段代码从语义执行上似乎都没有出现过任何问题,但是运行一段时间之后就导致崩溃,同时在C语言可变参数之中使用 STL容器(如 std::string)也会导致莫名其妙的崩溃,但在绝大多数时间内它都被正确执行。

解决这类问题在 C/C++ 语言之中,我们应当首选通过 C/C++ 动态参数模板来实现,例如:我们期望对于 snprintf 的动态参数转发,并且返回std::string字符串,正确做法与不正确做法。

正确:(一半,开O3后有一定崩溃风险,看脸运行时间多长)

    std::string test(const char* format, ...) noexcept {char buffer[8096];va_list ap;va_start(ap, format);vsnprintf(buffer, sizeof(buffer), format, args);va_end(ap);return buffer;}

正确:

    template <class... A>std::string                                     test(const char* format, A&&... args) noexcept {char buffer[8096];snprintf(buffer, sizeof(buffer), format, std::forward<A&&>(args)...);return buffer;}

错误:

    auto printfn = [](const char* format, ...) noexcept{va_list ap;va_start(ap, format);std::string st = test(format, ap);va_end(ap);};

即自己在 C/C++ 中声明了:
std::string test(const char* format, va_list args) noexcept;

调用 vsnprintf 函数传递C语言可变参数列表。

在封装C语言可变参数 ...(语法)方式在封装传递,100%会遭遇较为快速的程序崩溃,但也不是立马崩溃,一般性调试期间基本不会崩。

但也不意味着完全不崩,只是要等它重复次数足够多,就是需要一定时间,这并非内存损坏问题。

在 C/C++ 语言之中,必须通过可变参数模板方式来传递可变参数列表,否则都是不安全,存在不缺行崩溃风险的。


http://www.ppmy.cn/news/1383101.html

相关文章

rust 阿里云oss操作

在rust中如何操作阿里云oss文件&#xff0c;阿里云官方并没有提供这样的sdk&#xff0c;我们可以使用社区的aliyun-oss-rust-sdk库crate来实现。 功能列表 文件下载签名下载签名上传获取上传对象的policy上传本地文件上传内存文件文件删除 添加依赖 [dependencies] # 异步 a…

【SSM】任务列表案例 基本CRUD SSM整合

文章目录 一、案例功能预览二、接口分析三、前端工程导入四、后端程序实现和测试4.1 准备4.2 功能实现4.2.1 分页查询显示4.2.2 添加计划4.2.2 删除计划4.2.3 修改计划 4.3 前后联调 一、案例功能预览 Github 地址 &#xff1a; ssm-integration-part 二、接口分析 学习计划…

centos7 安装wps 依赖源libGLU.so.1()(64bit)

centos 在安装wps时会提示&#xff1a;依赖检测失败&#xff1a; libXss.so.1()(64bit)被需要 yum 或者apt安装依赖失败 手动搜索发现https://pkgs.org/download/libGLU.so.1()(64bit)可以下载。 完成验证 选择合适自己的系统&#xff0c;这里以centos7为例 进入红框所选择…

LLM推理框架Triton Inference Server学习笔记(一): Triton Inference Server整体架构初识

官方文档查阅: TritonInferenceServer文档 1. 写在前面 这篇文章开始进行大语言模型(Large Language Model, LLM)的学习笔记整理&#xff0c;这次想从Triton Inference Server框架开始&#xff0c;因为最近工作上用到了一些大模型部署方面的知识&#xff0c; 所以就快速补充了…

【Linux基础(三)】信号

学习分享 1、信号的基本概念2、查看信号列表3、常见信号名称4、signal库函数5、发送信号kill6、kill - signal &#xff08;无参信号&#xff09;示例6.1、kill - signal (不可靠信号)示例6.2、kill - signal (可靠信号)示例 7、信号分类7.1、信号运行原理分类7.2、信号是否携带…

Sklearn K-均值算法

以下是一个使用Sklearn库实现K-均值聚类算法的简单代码示例。K-均值算法是一种迭代算法&#xff0c;用于将数据集分为K个簇&#xff0c;使得每个簇的内部平方误差最小。 # 导入必要的库 from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score imp…

经典数组和指针笔试题解析——C语言

【本节内容】 1. 数组和指针笔试题解析 2. 指针运算笔试题解析 1. 数组和指针笔试题解析 1.1 一维数组 #include <stdio.h> int main() {int a[] { 1,2,3,4 };printf("%zd\n", sizeof(a));printf("%zd\n", sizeof(a 0));printf("%zd\n&qu…

宠物小精灵之收服

题目描述 宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事。 一天&#xff0c;小智和皮卡丘来到了小精灵狩猎场&#xff0c;里面有很多珍贵的野生宠物小精灵。小智也想收服其中的一些小精灵。然而&#xff0c;野生的小精灵并不那么容易被收服。对于每一个野生小精灵而…