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

WSL(Ubuntu20.04)下调用C标准库strcpy、strtol结果异常问题

问题产生原因

核心问题是重叠内存调用strcpy触发了未定义行为,具体执行流程拆解如下:

  1. 初始状态buf内容为a678b\0,第一次进入循环调用strtol(buf, &endptr, 10):
    • 首字符a不是十进制数字,strtol返回0,endptr直接指向buf的首地址(也就是a所在的位置)
  2. 进入x==0的分支,执行strcpy(buf, endptr + 1):
    • 此时endptr + 1等于buf + 1,即strcpy的源地址和目标地址是同一块内存的重叠区域
    • C标准明确规定strcpy不支持重叠内存拷贝,重叠场景下的执行结果是未定义的。你使用的WSL环境下glibc的strcpy有面向多字节的优化逻辑,不会按逐字节顺序拷贝,导致拷贝过程中源字符串的未读取内容被提前覆盖,最终得到错误的buf内容,累加后得到错误结果68。
修改后代码正常的原因

你新增了独立的中间缓冲区kk,先把endptr + 1指向的内容拷贝到和buf完全不重叠的kk中,再从kk拷贝到buf,两次strcpy的源、目标都不存在重叠,因此执行行为完全符合预期,最终累加得到正确结果678。

更简洁的修复方案

不需要额外的中间缓冲区,直接使用支持重叠内存拷贝的memmove函数即可:

if (x == 0) {
    memmove(buf, endptr + 1, strlen(endptr + 1) + 1);
}

memmove会先判断内存重叠方向,选择合适的拷贝顺序,保证内容拷贝正确。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:06:01