C++中memcpy和memmove的区别总结

 更新时间:2014年10月09日 11:24:02   作者:果冻想  
这篇文章主要介绍了C++中memcpy和memmove的区别总结,这个问题经常出现在C++的面试题目中,需要的朋友可以参考下

变态的命名

我们在写程序时,一般讲究见到变量的命名,就能让别人基本知道该变量的含义。memcpy内存拷贝,没有问题;memmove,内存移动?错,如果这样理解的话,那么这篇文章你就必须要好好看看了,memmove还是内存拷贝。那么既然memcpy和memmove二者都是内存拷贝,那二者究竟有什么区别呢?

先说memcpy

你有没有好好的参加过一场C++笔试。让你写出memcpy的实现,这是多么常见的笔试题啊。现在,拿起你的演算纸和笔;是的,是笔和纸,不是让你在你的IDE上写。写不出来?看下面吧:

复制代码 代码如下:

void *mymemcpy(void *dest, const void *src, size_t count)
{
    assert(dest != NULL || src != NULL);
   
    char *tmp = (char *)dest;
    char *p = (char *)src;
 
    while (count--)
    {
        *tmp++ = *p++;
    }
    return dest;
}

memcpy的实现很简单,一般在笔试时,出现写源码的题目,无非就是需要注意以下几点:

1.确定函数原型;
2.判断参数合法性;
3.逻辑实现(考虑各种情况,统称逻辑实现);
4.错误处理。

当然了,我的这个没有错误处理,也不需要错误处理。上面,我写出了memcpy的实现源码,实现原理如下图所示:

这样下去,上面的代码会运行的很好,如果出现下面的情况呢?

i、n、k的内存和J、e、l的内存地址重合了,现在再使用上面的代码进行copy时,会出现什么问题呢?你有没有想过这个问题。如果没有,那就现在想想,不急着阅读下面的内容。

然后,我再留一个问题,上面的代码中,为什么都需要将void *转换成char *呢?比如:

复制代码 代码如下:

char *tmp = (char *)dest;

可以留言回答哦。

再说memmove

memmove也是用来实现内存的直接拷贝的。说起这个命名,我个人觉的多少还是有点坑的。既然memmove也是用来内存数据移动的,那就先来看看memmove的实现源码。

复制代码 代码如下:

void *mymemmove(void *dest, const void *src, size_t count)
{
    assert(dest != NULL || src != NULL)
 
    if (dst < src)
    {
        char *p = (char *)dest;
        char *q = (char *)src;
        while (count--)
        {
            *p++ = *q++;
        }
    }
    else
    {
        char *p = (char *)dest + count;
        char *q = (char *)src + count;
        while (count--)
        {
            *--p = *--q;
        }
    }
 
    return dest;
}

从源码看,memmove的确比memcpy复杂一些;再仔细一看,多了些什么?哦,多了一个else分支,而正是这个else分支,就处理了当src和dest的内存重合的问题。

memcpy和memmove的比较

从实现源码中的确能看出一些猫腻,当出现了src和dest的内存有重合的时机时,memmove的处理规则是从后往前进行copy。当然了,重合的问题,需要考虑的以下两种场合。

如图所示,当出现(1)对应的情况时,就需要先从src的头部开始复制;也就是memmove源码中的if分支,这部分源码和memcpy的实现是一致的;当出现(2)对应的情况时,就需要先从src的尾部开始复制,防止出现了覆盖现象。这就是memmove比memcpy多的一个考虑点,所以说,在实际使用时,使用memmove是比memcpy更安全的。

总结

总结到了这里,我觉的我已经把问题说清楚了。你说呢?如果你还有什么好的想法,欢迎你和我分享。

相关文章

  • 一文详解C++中隐含的this指针

    一文详解C++中隐含的this指针

    这篇文章主要带大家详细了解一下C++中隐含的this指针,文中通过代码示例和图文介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-01-01
  • C++ 中const 类型限定符不兼容问题

    C++ 中const 类型限定符不兼容问题

    这篇文章主要介绍了C++ 中const 类型限定符不兼容问题的相关资料,需要的朋友可以参考下
    2015-06-06
  • 详解C++的静态内存分配与动态内存分配

    详解C++的静态内存分配与动态内存分配

    内存分配 (Memory Allocation) 是指为计算机程序或服务分配物理内存空间或虚拟内存空间的一个过程,本文主要介绍了C++的静态内存分配与动态内存分配,感兴趣的同学可以参考阅读
    2023-06-06
  • C语言用easyx实现消砖块游戏

    C语言用easyx实现消砖块游戏

    这篇文章主要为大家详细介绍了C语言消砖块游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • C++将模板实现放入头文件原理解析

    C++将模板实现放入头文件原理解析

    这篇文章主要为大家介绍了C++将模板实现放入头文件原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • c++中八大排序算法

    c++中八大排序算法

    本篇文章主要介绍了八大排序算法,详细的介绍了八个算法思想,实现代码,稳定性,时间复杂度等,具有一定的参考价值,有需要的可以了解一下。
    2016-11-11
  • C 程序实现密码隐秘输入的实例 linux系统可执行

    C 程序实现密码隐秘输入的实例 linux系统可执行

    下面小编就为大家带来一篇C 程序实现密码隐秘输入的实例 linux系统可执行。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • C语言实现经典小游戏井字棋的示例代码

    C语言实现经典小游戏井字棋的示例代码

    这个三子棋游戏是在学习C语言的过程中自己编写的一个小游戏,现在将自己的思路(主要以流程图形式和代码中的注释表达)和具体代码以及运行结果分享出来以供大家学习参考,希望对大家有所帮助
    2022-11-11
  • C语言控制进程之进程等待详解

    C语言控制进程之进程等待详解

    这篇文章主要介绍了C语言控制进程之进程等待即回收子进程的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • C++实现简易UDP网络聊天室

    C++实现简易UDP网络聊天室

    这篇文章主要为大家详细介绍了C++实现简易UDP网络聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07

最新评论