memmove/memcpy/strcpy 原型中的第二个参数类似:例如:
void *memmove(void *dest, const void *src, size_t n); //const void*
char *strcpy(char *dest, const char *src); //const char*
但显然,如果 dest 和 src 重叠,那么 src 的内容将会改变,违反了 const void/char *?
const void*
表示不会通过该指针修改引用。
如果还有其他指向同一对象的非常量指针(也称为“别名”),那么当然仍然可以通过这些指针对其进行修改。在您描述的场景中,另一个指针是dest
.
顺便说一句,在 的情况下strcpy
,如果区域重叠,则行为是不确定的,而在 C99 中,签名是char *strcpy(char * restrict s1, const char * restrict s2);
。但是对于 memmove,别名是可以的。通过给它重叠区域,你已经给了它修改dest
区域的“权限”,它会这样做。
该参数被标记const void *
为表示memmove
永远不会修改src
使用该指针指向的内存。如果发生重叠,则使用dest
指针而不是src
指针修改内存,因此不违反保证。
这意味着memmove
保证它不会直接修改src
.
当然如果两个块重叠memmove
会改变所谓的“const”内存。const
是附加在名称上的合同。没有办法将实际内存设为只读。
如上 memove 不会通过“src”指针修改内存内容,而是通过“dest”指针。
const 指的是如何使用指针,它不添加任何内存保护。
如果两个指针都指向内存的重叠区域,那么任何事情都可能发生,因为如果副本将从“src”开始并递增或从“src + n”开始并递减,则未定义。