memcpy(buf, buf + (pos - offset), len);
而,
0<=pos<=strlen(buf), 0<=offset<=strlen(buf)
在这种情况下使用memcpy()
是否安全?如果没有,会出现什么问题?请提出最佳做法。
答案 0 :(得分:8)
不,不是。请改用memmove
。
如果使用 start end value
0 0 37647 0
1 37648 37846 1
2 37847 42874 0
3 42875 43049 1
4 43050 51352 0
5 51353 51665 -1
6 51666 55259 0
时内存区域重叠,则行为未定义。虽然可能似乎可以正常工作。
参考文献:
答案 1 :(得分:2)
自C99起,memcpy具有以下声明
void* memcpy(void *restrict dest, const void *restrict src, size_t count);
restrict
是一个关键字,它告诉编译器只能通过指针本身访问指针的对象。本质上,这意味着编译器(以及memcpy
的实现者)可以假设这两个区域不重叠。
因此,例如,如果通过从头开始复制字节的简单迭代实现memcpy
,只要区域不重叠,一切都会好的,事实上如果源区域会好的话在目的地区域之上。但是,如果区域重叠并且源区域位于比目标区域低的地址,则源区域的末端将在复制之前被副本破坏。如果pos - offset < 0
和offset - pos < len
您也不能认为这是唯一出错的可能性,某些计算机体系结构的指令可能会更快地从顶部开始复制并向下工作,在这种情况下memcpy
是安全的在目的地下方并重叠,但不在目的地上方并重叠。如果len > pos - offset
因此,如果有任何重叠的可能性,请始终使用memmove
。但是,如果len <= pos - offset
您是安全的,因为保证您的两个区域不会重叠。