memmove / memcpy / strcpy原型中的第二个arg是类似的: 例如:
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 *?
答案 0 :(得分:20)
const void*
表示不会通过该指针修改参考号。
如果存在指向同一对象的其他非常量指针(也称为“别名”),那么当然它仍然可以通过这些指针进行修改。在您描述的场景中,其他指针是dest
。
顺便说一下,在strcpy
的情况下,如果区域重叠,则行为未定义,而在C99中,签名为char *strcpy(char * restrict s1, const char * restrict s2);
。但是对于memmove,别名是可以的。通过给予重叠区域,您已经“允许”修改dest
区域,并且它会这样做。
答案 1 :(得分:7)
参数标记为const void *
,表示memmove
永远不会使用该指针修改src
指向的内存。如果发生重叠,则使用dest
指针而不是src
指针修改内存,因此不会违反保证。
答案 2 :(得分:4)
这意味着memmove
保证不会直接修改src
指向的内存。
当然,如果两个块重叠memmove
将改变所谓的“const”内存。 const
是附加在名称上的合同。无法将实际内存设为只读。
答案 3 :(得分:4)
如上所述,memove不会通过“src”指针修改内存的内容,而是通过“dest”指针修改内存。
const指的是如何使用指针,它不会添加任何内存保护。
如果两个指针都指向内存的重叠区域,那么任何事情都可能发生,因为如果副本将从“src”开始并从“src + n”开始递增或开始减少而无法定义。