You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言sprintf字符串终止错误:预期行为与原因问询

sprintf代码片段的预期行为与字符串终止错误分析

先看代码:

sprintf(workbuf,
        "(C)(0225,0181) %6.6s HDR REC BAD TRAN_SETL_FNUM, OFFSET %ld, LEN %ld, FILE=[%s/%s]",
        tranHdr->lu.source_path_name, offsetof(RTPN_HEADER_REC, tran_setl_fnum),
        sizeof(rtpn_hdr->tran_setl_fnum), pathPtr->inFileName, pathPtr->userFileName);

预期行为

这段代码的目标是生成一条格式化的错误日志,写入workbuf缓冲区:

  • 开头固定输出(C)(0225,0181) 标识
  • 截取tranHdr->lu.source_path_name的前6个字符(不足6位时左侧补空格,超过6位时只取前6位)
  • 输出结构体成员tran_setl_fnum在RTPN_HEADER_REC中的偏移量(由offsetof计算)
  • 输出tran_setl_fnum成员的字节大小(由sizeof计算)
  • 最后拼接pathPtr->inFileName和pathPtr->userFileName成路径,放在FILE=[]中
  • 按照sprintf的正常逻辑,会自动在workbuf末尾添加\0字符串终止符,保证结果是合法的C字符串

字符串终止错误的原因

常见的触发原因有三个:

  1. 参数类型不匹配导致解析错位
    sizeof返回的是size_t类型,但格式化符用了对应long类型的%ld。在64位系统中,size_t是64位、long是32位,这种类型不匹配会让sprintf读取参数时栈位置偏移,后续的字符串参数pathPtr->inFileName、pathPtr->userFileName被错误解析,破坏内存结构,最终无法正常写入\0终止符。

  2. 缓冲区空间不足引发溢出
    如果workbuf的分配大小小于格式化后字符串的总长度,sprintf会直接越界写入,覆盖缓冲区后方的内存——这其中就包含原本要存放\0的位置,导致字符串没有合法终止符。

  3. 输入字符串本身不合法
    若tranHdr->lu.source_path_name是未以\0终止的字符数组,%6.6s读取时会越界访问内存,不仅会读到垃圾数据,还会干扰后续参数的解析流程,导致整个格式化过程出错,终止符无法正常写入。

内容的提问来源于stack exchange,提问作者jit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:38:25