memcpy 绝对是 C++里的史前巨坑!

查看 239|回复 10
作者:tool2d   
都说圣斗士不会在同一套招式下倒下两次,我偏偏就在同一个坑里,掉进去了两次。
最近写了一个服务器程序,会随机出现一些乱字符,很不好调试,查了半天,发现是 memcpy 复制的时候,有 overlapping buffer 内存,而这个行为在 C++标准里, 是 UB 行为,官方允许复制结果出错!
windows 上有类似功能的函数,叫 CopyMemory ,就从来没出过这种情况,真是大意了。
其实以前遇到过这个 bug ,查到有资料说,高版本 linux 会自动判断输入范围,自动改成 memmove ,就轻视了。没想到后来 glibc 为了性能优化,中间又给改回去了。真是晕过去,API 行为都能反复横跳的吗?
我再也不想用 memcpy 了,别和我说什么优化和性能,以后只用 memmove 走天下。

memcpy, memmove, 套招式, 巨坑

greensea   
我觉得 memcpy 不检查边界这件事情对 C 程序员来说应该是常识来着的
optional   
有时候 memcpy 的结果才是你想要的呢。
zagfai   
我觉得 memcpy 不检查边界这件事情对 C 程序员来说应该是常识来着的
lwh0328   
我也觉得 memcpy 不检查边界这件事情对 C 程序员来说应该是常识来着的
dodng12   
我也觉得 memcpy 不检查边界这件事情对 C 程序员来说应该是常识来着的
tool2d
OP
  
@greensea 习惯了 windows 开发,memcpy 从来就不需要额外检测,自动处理同一块内存里的复制搬运。微软就是一个好保姆,一切都默默帮你处理好了。
memcpy 行为和 windows 相差甚远,单纯为了性能,我也是能理解的。但不能说 glibc 改了一半后,高版本号又给改了回去啊。这不算偷袭老年人嘛。
https://man7.org/linux/man-pages/man3/memcpy.3.html 里 note 部分,写明了部分 glibc 版本的影响范围,我就中招了。
FaiChou   
确实要注意下, memmove 如果碰到 src 地址小于 dest, 会从尾巴地方往后处理, 这样就避免了 overlapping 数据
blinue   
windows 里也不允许 https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy-wmemcpy
lixile   
asan msan tsan lsan ubsan 五管齐下 可以用工具检测
您需要登录后才可以回帖 登录 | 立即注册

返回顶部