memmove中的“const void *”是啥意思?

Posted

技术标签:

【中文标题】memmove中的“const void *”是啥意思?【英文标题】:what does the "const void*" mean in memmove?memmove中的“const void *”是什么意思? 【发布时间】:2011-11-18 16:59:56 【问题描述】:

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 *?

【问题讨论】:

【参考方案1】:

const void* 表示不会通过该指针修改引用

如果有其他指向同一对象的非常量指针(也称为“别名”),那么当然仍然可以通过这些指针对其进行修改。在您描述的场景中,另一个指针是dest

顺便说一下,在strcpy 的情况下,如果区域重叠,则行为是未定义的,而在C99 中签名是char *strcpy(char * restrict s1, const char * restrict s2);。但是对于 memmove,别名是可以的。通过给它重叠区域,你已经给它“权限”来修改dest 区域,它会这样做。

【讨论】:

你的意思是,如果我不能确定dest和src是否重叠,我最好不要使用strcpy,对吗? @Alcott:没错。在实践中您最有可能看到的是,如果您的区域与dest < src 重叠,那么它将起作用。如果它们与src < dest 重叠,则src 末尾的nul 字节将在读取之前被覆盖,然后该函数将进入无限循环破坏内存,直到发生某些终端事件。但你不能依赖其中任何一种行为。【参考方案2】:

如上memove不会通过“src”指针修改内存内容,而是通过“dest”指针。

const 指的是如何使用指针,它不添加任何内存保护。

如果两个指针都指向内存的重叠区域,那么任何事情都可能发生,因为它没有定义如果副本将从“src”开始并递增或从“src + n”开始并递减。

【讨论】:

抱歉,我在编辑上述内容的同时发布了一个重复的答案 这种事情一直在发生,这不是问题。即使答案基本相同,答案通常也会存在细微差别,而且对同一事物有多种解释通常非常有用 - 一位读者会最好地理解其中一个,而其他人会理解另一个。【参考方案3】:

参数标记为const void *,表示memmove 永远不会使用该指针修改src 指向的内存。如果发生重叠,则使用dest 指针而不是src 指针修改内存,因此不会违反保证。

【讨论】:

【参考方案4】:

表示memmove保证不会直接修改src指向的内存。

当然如果两个块重叠memmove会改变所谓的“const”内存。 const 是附加到名称的 ca 合同。无法将实际内存设为只读。

【讨论】:

@Praetorian 我经常不知道我在说什么,但我喜欢 cmets 所以我可以学习 :-)

以上是关于memmove中的“const void *”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

memmove 和 memcpy的区别

memmove 和 memcpy的区别

将 const void* 转换为 const int*

qsort 给出 [错误]:从 `int (*)(cricketer*, cricketer*)' 到 `int (*)(const void*, const void*)' 的无效转换

算法-memcopy与memmove的区别

invalid conversion from `const void*' to `void*'