C/C++ memmove与memcpy的区别及实现
2016-05-18 23:18
531 查看
1.与字符串函数strcpy区别:
memcpy与memmove都是对内存进行拷贝可以拷贝任何内容,而strcpy仅是对字符串进行操作。
memcpy与memmove拷贝多少是通过其第三个参数进行控制而strcpy是当拷贝至'\0'停止。
2.函数说明:
memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝N个字节到目标dst所指的内存地址的起始位置中。
memmove函数的功能同memcpy基本一致,但是当src区域和dst内存区域重叠时,memcpy可能会出现错误,而memmove能正确进行拷贝。
3.拷贝情况:
拷贝的具体过程根据dst内存区域和src内存区域可分为三种情况:
1.当src内存区域和dst内存区域完全不重叠
![](http://img.blog.csdn.net/20160518223324408?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
2.当src内存区域和dest内存区域重叠时且dst所在区域在src所在区域前
![](http://img.blog.csdn.net/20160518223043078?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
3.当src内存区域和dst内存区域重叠时且src所在区域在dst所在区域前
![](http://img.blog.csdn.net/20160518223515892?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
上述三种情况,memcpy可以成功对前两种进行拷贝,对第三种情况进行拷贝时,由于拷贝dst前两个字节时覆盖了src原来的内容,所以接下来的拷贝会出现错误。而memmove对第三种情况进行拷贝时会从src的最后向前拷贝N个字节,避免了覆盖原来内容的过程。
4.代码实现
memcpy:
如有错误请指出,谢谢
memcpy与memmove都是对内存进行拷贝可以拷贝任何内容,而strcpy仅是对字符串进行操作。
memcpy与memmove拷贝多少是通过其第三个参数进行控制而strcpy是当拷贝至'\0'停止。
2.函数说明:
memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝N个字节到目标dst所指的内存地址的起始位置中。
memmove函数的功能同memcpy基本一致,但是当src区域和dst内存区域重叠时,memcpy可能会出现错误,而memmove能正确进行拷贝。
3.拷贝情况:
拷贝的具体过程根据dst内存区域和src内存区域可分为三种情况:
1.当src内存区域和dst内存区域完全不重叠
2.当src内存区域和dest内存区域重叠时且dst所在区域在src所在区域前
3.当src内存区域和dst内存区域重叠时且src所在区域在dst所在区域前
上述三种情况,memcpy可以成功对前两种进行拷贝,对第三种情况进行拷贝时,由于拷贝dst前两个字节时覆盖了src原来的内容,所以接下来的拷贝会出现错误。而memmove对第三种情况进行拷贝时会从src的最后向前拷贝N个字节,避免了覆盖原来内容的过程。
4.代码实现
memcpy:
void* _memcpy(void* dest, const void* src, size_t count) { assert(src != nullptr&&dest != nullptr); //判断dest指针和src指针是否为空,若为空抛出异常 char* tmp_dest = (char*)dest; const char* tmp_src = (const char*)src; //将指针dest和指针src由void强转为char, //使得每次均是对内存中的一个字节进行拷贝 while (count--) *tmp_dest++ = *tmp_src++; return dest; }memmove:
void* _memmove(void* dest, const void* src, size_t count) { assert(src != nullptr&&dest != nullptr); //判断dest指针和src指针是否为空,若为空抛出异常 char* tmp_dest = (char*)dest; const char* tmp_src = (const char*)src; if (tmp_src < tmp_dest)//当src地址小于dest地址时,从头进行拷贝 while (count--) *tmp_dest++ = *tmp_src++; else if (tmp_src > tmp_dest)//当src地址大于dest地址时,从后进行拷贝 { tmp_src += count - 1; tmp_dest += count - 1; while (count--) *tmp_dest-- = *tmp_src; } //else(tmp_src==tmp_dest) 此时不进行任何操作 return dest; }
如有错误请指出,谢谢
相关文章推荐
- 适配器模型-c++实现
- 四则运算
- C语言任意交换两种类型变量
- 浅谈c++的继承
- 【C/C++】:sizeof详解
- c++调试快捷键
- C++之各种二叉树的遍历
- 面筋: 奇虎360 c++ 后台开发 实习生 面试
- 镜花水月,过不留痕————铭记那些给我们带来进步的C语言小难题<2>
- 谭浩强C程序设计基础数组知识点总结一
- 题目1
- 指针
- C++ __super
- C++笔记1.0 外部输入数组n,定义一个数组,从外面输入n个数依次放入数组
- #hiho1099 Constellations枚举法的应用
- C++版学生信息管理系统
- C++学习笔记(五)迭代器iterator
- 镜花水月,过不留痕————铭记那些给我们带来进步的C语言小难题
- 【C++】:C++中的static关键字
- C语言版的日历