【问题标题】: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 *?

【问题讨论】:

    标签: c constants strcpy memmove


    【解决方案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 所以我可以学习 :-)
      猜你喜欢
      • 2018-05-12
      • 1970-01-01
      • 2020-05-01
      • 2013-03-09
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多