L云笔记

  • 首页
  • 示例页面
  • 网络收藏夹
L's cloud note
一个用于记录 分享的博客
  1. 首页
  2. 技能类
  3. c/c++
  4. 正文

va_start不支持可重入

2021年11月21日 202点热度 0人点赞 0条评论

1 打印乱码现象:

[Mon Nov 15 10:59:51 2021] Failed to create http session, 192.168.1.1 tmp 榜?tmp2 192.168.1.3 tmp3 榜?ip H塃鳫婨鳫?111
va_start(ap, fmt);
//xxx_sprintf(buff_log, fmt, ap); //改成这句打印乱码
xxx_vsprintf(buff_log, fmt, ap, true); //改成这句后打印正确
va_end(ap);

2 错误原因:

  1. xxx_sprintf(buff_log, fmt, ap);已经包含了va_start
template
int xxx_sprintf(std::basic_string& s, const T* fmt, …)
{
va_list ap;
<strong>va_start</strong>(ap, fmt);
const int rc = string_vsprintf(s, fmt, ap);
va_end(ap);
return rc;
}

2.在C中实现变量参数访问的方式使得很明显va_list对象存储了一些内部状态。这使得它不可重入,这意味着在va_list对象上调用va_start将使前一个va_start的效果无效。但更准确地说,C在使用va_end“关闭”先前调用的va_start会话之前,明确禁止在va_list对象上再次调用va_start。va_list对象应该以“非重叠”方式使用:va_start…va_end。之后,您可以在同一个va_list对象上执行另一个va_start。但是尝试在同一个va_list对象上重叠va_start…va_end会话将不起作用。应参考以下,使用va_copy()

int xxx_vsprintf(std::basic_string& s, const T* fmt, va_list args, bool append)
{
    va_list ap;
    va_copy(ap, args);
    int len = ACE_OS::vsnprintf(&s[0] + pos, size, fmt, ap);
    va_end(ap);
}

3 相关链接:

https://oomake.com/question/901815
https://blog.csdn.net/f110300641/article/details/83822290

标签: 暂无
最后更新:2021年11月21日

李大锤

这个人很懒,什么都没留下

打赏 点赞

文章评论

取消回复

COPYRIGHT © 2021 leyi.space. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

鄂ICP备2021019672号

| 总访问量 次 | 总访客数 人