像这样使用 memcpy 安全吗?
Is it safe to use memcpy like this?
memcpy(buf, buf + (pos - offset), len);
然而,
0<=pos<=strlen(buf), 0<=offset<=strlen(buf)
在这种情况下使用 memcpy()
安全吗?如果没有,会出什么问题?请提出最佳做法。
不,不是。请改用 memmove
。
如果使用 memcpy
时内存区域重叠,则行为未定义。尽管它 可能 看起来有效,具体取决于实施情况。
参考文献:
从 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
你是安全的,因为你的两个区域保证不会重叠。
memcpy(buf, buf + (pos - offset), len);
然而,
0<=pos<=strlen(buf), 0<=offset<=strlen(buf)
在这种情况下使用 memcpy()
安全吗?如果没有,会出什么问题?请提出最佳做法。
不,不是。请改用 memmove
。
如果使用 memcpy
时内存区域重叠,则行为未定义。尽管它 可能 看起来有效,具体取决于实施情况。
参考文献:
从 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
你是安全的,因为你的两个区域保证不会重叠。