1
greensea 2023-03-23 15:56:41 +08:00 18
我觉得 memcpy 不检查边界这件事情对 C 程序员来说应该是常识来着的
|
2
optional 2023-03-23 15:57:16 +08:00 via iPhone 2
有时候 memcpy 的结果才是你想要的呢。
|
3
zagfai 2023-03-23 15:57:54 +08:00
我觉得 memcpy 不检查边界这件事情对 C 程序员来说应该是常识来着的
|
4
lwh0328 2023-03-23 16:03:38 +08:00
我也觉得 memcpy 不检查边界这件事情对 C 程序员来说应该是常识来着的
|
5
dodng12 2023-03-23 16:04:42 +08:00
我也觉得 memcpy 不检查边界这件事情对 C 程序员来说应该是常识来着的
|
6
tool2d OP @greensea 习惯了 windows 开发,memcpy 从来就不需要额外检测,自动处理同一块内存里的复制搬运。微软就是一个好保姆,一切都默默帮你处理好了。
memcpy 行为和 windows 相差甚远,单纯为了性能,我也是能理解的。但不能说 glibc 改了一半后,高版本号又给改了回去啊。这不算偷袭老年人嘛。 https://man7.org/linux/man-pages/man3/memcpy.3.html 里 note 部分,写明了部分 glibc 版本的影响范围,我就中招了。 |
7
FaiChou 2023-03-23 16:05:32 +08:00
确实要注意下, memmove 如果碰到 src 地址小于 dest, 会从尾巴地方往后处理, 这样就避免了 overlapping 数据
|
8
blinue 2023-03-23 16:07:02 +08:00
|
9
lixile 2023-03-23 16:09:52 +08:00
asan msan tsan lsan ubsan 五管齐下 可以用工具检测
|
10
cy18 2023-03-23 16:12:35 +08:00
说出来是知道的,但是时间久了容易忘,还是得靠工具检查。
|
11
koebehshian 2023-03-23 16:58:09 +08:00
有重叠用 memmove ,没有重叠用 memcpy ,memcpy 都让传长度了,有没有溢出肯定程序员负责的。刚学 C 的时候,一看这俩函数功能差不多,就仔细查一下它们的区别。
|
12
sloknyyz 2023-03-23 17:07:54 +08:00
你通过正经手段分配的两段内存怎么可能会重叠。还不是因为自己指针搞来搞去,出事了又来怪 memcpy 。
|
13
tool2d OP |
14
tool2d OP @koebehshian 也就是多一个 if 判断的问题,我已经打算自己写一个封装函数了。
if (dst <= src || dst >= (src + count)) { // Non-Overlapping Buffers memcpy(); } else { memmove(); } |
15
nmap 2023-03-23 17:39:38 +08:00
自己菜,这个问题属于常识
|
16
ivvei 2023-03-23 17:54:34 +08:00
UB 就是这样的了,一个版本一个样也不奇怪。
|
17
icyalala 2023-03-23 18:07:56 +08:00 4
memcpy 对于 overlap UB 这个是写文档里的。。更早之前 glibc 的 memcpy 刚好对 overlap 还没问题,然后 2010 年马凌提了个性能优化的 patch ,性能有提升,但对 overlap 不支持了。正好 Adobe 程序员和楼主一样乱用,然后导致 flash 出现爆音之类的问题,当时很多人来辩论,甚至 Linus 还过来骂了几句: https://bugzilla.redhat.com/show_bug.cgi?id=638477
那个作者还在知乎,楼主可以去对线: https://www.zhihu.com/question/35172305/answer/73698602 |
18
ysc3839 2023-03-23 18:18:14 +08:00 via Android
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa366535(v=vs.85)
If the source and destination blocks overlap, the results are undefined. For overlapped blocks, use the MoveMemory function. |
19
nightwitch 2023-03-23 18:30:42 +08:00 1
#14 楼的代码有什么意义。。memmove 里自带这个判断。
最好的办法就是当 memcpy 这个函数不存在,memmove 是它的上位替代 |
20
junkun 2023-03-23 22:18:39 +08:00 2
历史遗留问题,名字取得不好。rust 里这两个函数就改成了 std::ptr::copy 和 copy_nonoverlapping ,这就没人会认错了。
|
21
Cormic 2023-03-23 22:23:30 +08:00
老话说得好:没有金箍棒别揽瓷器活
|
22
xarthur 2023-03-23 22:25:01 +08:00 via iPhone
UB 害人(
|
23
k9982874 2023-03-23 22:27:35 +08:00 via Android
菜是原罪
|
24
xuboying 2023-03-24 10:18:05 +08:00
都说的很好,但是这好像是 C 的问题,C++干嘛要背锅。。。
|
25
yolee599 2023-03-24 10:36:44 +08:00
memcpy 这个应该是一个程序中用得最多的函数,要求必须是高性能的,如果它内部加了很多判断,这样每调用一次性能都有损失。一个程序中有很多 memcpy 损失的性能就很可观了,因为大部分场景不需要 overlapping 但还是做了判断。
|
26
Yeen 2023-03-24 10:52:58 +08:00
我记得多年前,很多公司会专门用 memcpy 的传递参数顺序来出题。
|
27
tool2d OP |
28
smdbh 2023-03-24 15:30:10 +08:00
感觉是用 memcpy 干 memmove 的活啊
|