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

2023-03-23 15:50:14 +08:00
 tool2d
都说圣斗士不会在同一套招式下倒下两次,我偏偏就在同一个坑里,掉进去了两次。

最近写了一个服务器程序,会随机出现一些乱字符,很不好调试,查了半天,发现是 memcpy 复制的时候,有 overlapping buffer 内存,而这个行为在 C++标准里, 是 UB 行为,官方允许复制结果出错!

windows 上有类似功能的函数,叫 CopyMemory ,就从来没出过这种情况,真是大意了。

其实以前遇到过这个 bug ,查到有资料说,高版本 linux 会自动判断输入范围,自动改成 memmove ,就轻视了。没想到后来 glibc 为了性能优化,中间又给改回去了。真是晕过去,API 行为都能反复横跳的吗?

我再也不想用 memcpy 了,别和我说什么优化和性能,以后只用 memmove 走天下。
5186 次点击
所在节点    C++
28 条回复
Cormic
2023-03-23 22:23:30 +08:00
老话说得好:没有金箍棒别揽瓷器活
xarthur
2023-03-23 22:25:01 +08:00
UB 害人(
k9982874
2023-03-23 22:27:35 +08:00
菜是原罪
xuboying
2023-03-24 10:18:05 +08:00
都说的很好,但是这好像是 C 的问题,C++干嘛要背锅。。。
yolee599
2023-03-24 10:36:44 +08:00
memcpy 这个应该是一个程序中用得最多的函数,要求必须是高性能的,如果它内部加了很多判断,这样每调用一次性能都有损失。一个程序中有很多 memcpy 损失的性能就很可观了,因为大部分场景不需要 overlapping 但还是做了判断。
Yeen
2023-03-24 10:52:58 +08:00
我记得多年前,很多公司会专门用 memcpy 的传递参数顺序来出题。
tool2d
2023-03-24 11:06:03 +08:00
@yolee599 我已经掉坑里两次了,绝对不想要第三次的体验。已经全局#undef memcpy 了,全部走封装函数。

UB 不是说能稳定复现的 BUG ,我宁可每次调用函数前,多判断一次的,牺牲不了什么性能。


@ysc3839
文档虽让这样说,但其实微软的 memcpy 是 crt 里开源的代码,感觉从来没出现过这类问题。我试了一下安卓,也没问题。仅仅是部分 linux 下的 glibc 有问题。
smdbh
2023-03-24 15:30:10 +08:00
感觉是用 memcpy 干 memmove 的活啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/926553

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX