memmove 和 memcpy的区别以及处理内存重叠问题
区别:
memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下:
void *memcpy(void *dst, const void *src, size_t count);
void *memmove(void *dst, const void *src, size_t count);
他们的作用是一样的,唯一的区别是,当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确。
一、memcpy函数
Memcpy原型:
void *memcpy(void *dest, const void *src, size_t n);
描述:
memcpy()函数从src内存中拷贝n个字节到dest内存区域,但是源和目的的内存区域不能重叠。
返回值:
memcpy()函数返回指向dest的指针。
二、memmove函数
memmovey原型:
void *memmove(void *dest, const void *src, size_t n);
描述:
memmove() 函数从src内存中拷贝n个字节到dest内存区域,但是源和目的的内存可以重叠。
返回值:
memmove函数返回一个指向dest的指针。
从上面的描述中可以看出两者的唯一区别就是在对待重叠区域的时候,memmove可以正确的完成对应的拷贝,而memcpy不能。
内存覆盖的情形有以下两种,
先看memcpy()和memmove()这两个函数的实现:
void* my_memcpy(void* dst, const void* src, size_t n)
{
char *tmp = (char*)dst;
char *s_src = (char*)src; while(n--) {
*tmp++ = *s_src++;
}
return dst;
}
从实现中可以看出memcpy()是从内存左侧一个字节一个字节地将src中的内容拷贝到dest的内存中,这种实现方式导致了对于图中第二种内存重叠情形下,最后两个字节的拷贝值明显不是原先的值了,新的值是变成了src的最开始的2个字节了。
而对于第一种内存覆盖情况,memcpy的这种拷贝方式是可以的。
而memmove就是针对第二种内存覆盖情形,对memcpy进行了改进,改进代码如下:
void* my_memmove(void* dst, const void* src, size_t n)
{
char* s_dst;
char* s_src;
s_dst = (char*)dst;
s_src = (char*)src;
if(s_dst>s_src && (s_src+n>s_dst)) { //-------------------------第二种内存覆盖的情形。
s_dst = s_dst+n-1;
s_src = s_src+n-1;
while(n--) {
*s_dst-- = *s_src--;
}
}else {
while(n--) {
*s_dst++ = *s_src++;
}
}
return dst;
}
在第二种内存覆盖的情形下面,memcpy会出错,但是memmove是能正常工作的。
赐教!
memmove 和 memcpy的区别以及处理内存重叠问题的更多相关文章
- memmove 和 memcpy的区别
memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下:void *memcpy(void *dst, const void * ...
- C/C++ memmove与memcpy的区别及实现
1.与字符串函数strcpy区别: memcpy与memmove都是对内存进行拷贝可以拷贝任何内容,而strcpy仅是对字符串进行操作. memcpy与memmove拷贝多少是通过其第三个参数进行控制 ...
- C语言标准库函数memcpy和memmove的区别以及内存重叠问题处理
①memcpy()和memmove()都是C语言中的标准库函数,定义在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, cons ...
- [整理]内存重叠之memcpy、memmove
函数原型: void *memcpy( void *dest, const void *src, size_t count ); void *memmove( void* dest, const vo ...
- memmove和memcpy函数的区别及实现
一.memmove()和memcpy()函数和strcpy()函数的区别: (1)使用的类型不同,strcpy()函数只对字符串进行操作:memmove()和memcpy()函数对所有类型都适用,为内 ...
- 内存操作函数memmove,memcpy,memset
通过字符串的学习,我们知道字符串操作函数的操作对象是字符串,并且它的结束标志是结束符\0,当然这个说的是不 受限制的字符串函数.然而当我们想要将一段内存的数据复制到另一块内存时,我们不能使用字符串操作 ...
- strcpy,memcpy,memmove和内存重叠分析
一:strcpy函数用法和实现: /* GNU-C中的实现(节选): */ char* strcpy(char *d, const char *s) { char *r=d; while((*d++= ...
- memmove和memcpy
1.memmove 函数原型:void *memmove(void *dest, const void *source, size_t count) 返回值说明:返回指向dest的void *指针 参 ...
- memmove和memcpy 以及strcmp strcpy几个库函数的实现
memmove和memcpy 1.memmove 函数原型:void *memmove(void *dest, const void *source, size_t count) 返回值说明:返回指向 ...
随机推荐
- JavaScript的那些事儿
关于JavaScript的对象数据类型: Object 定义一个对象类型: 例如:var person=new Object(): 当然在建立对象以后我们可以为他添加属性, 如: <script ...
- [JZOJ5522] 图
题目大意: 一个有向图,图中有\(n\)个点\(m\)条边且无重边无自环, 每秒第\(i\)条边出现的概率是\(\frac{p[i]}{100}\), 一开始\(Samjia\)在\(1\)点,每一秒 ...
- Springboot项目如何把项目运行在服务器上
作为一个开发者,不可避免的要把本地项目变成可以接入外网的上线项目,今天来记录下springboot框架下如果把项目打包放在服务器上运行 第一步,首先要买个服务器,这个一般甲方会提供 第二步,导入jar ...
- 【python学习笔记】4.字典:当索引不好用时
[python学习笔记]4.字典:当索引不好用时 字典是python中唯一内建的map类型 创建: key可以为任何不可改变的类型,包括内置类型,或者元组,字符串 通过大括号: phonebook={ ...
- Linux-Centos7----安装Python的psutil模块插件
# wget https://pypi.python.org/packages/source/p/psutil/psutil-2.1.3.tar.gz # tar zxvf psutil-2.1.3. ...
- redis五种基本类型CRUD操作
1.String 增:set key1 value1 改:set key1 new-value.自增 incr key1.按照特定值递增:increby key1 inrevalue 删:del ke ...
- unix及Linux发展历程
unix及Linux发展历程 版权申明:本文资料为网上收集,由本人整理而成,转载请注明 一,unix诞生: Ken Thompson肯·汤普森 -------- unix之父 在1969年到1970间 ...
- VS调试再次遭遇“应用程序中断模式”问题,附解决方法
最近重构某项目过程中发现的,有同事反馈调试不正常,很久以前也发生过,虽然搜索了一下找到解决方案,但个人觉得还是有必要再记录一下. 调试某CS结构的应用程序,大致效果可以看下图: 我们组最终解决方案是: ...
- Java线程sleep,yield,join,wait方法详解
1.sleep() 当一个线程调用sleep方法后,他就会放弃cpu,转到阻塞队列,sleep(long millis)方法是Thread类中的静态方法,millis参数设定线程睡眠的时间,毫秒为单位 ...
- [Luogu 1395] 会议
题目 Description 有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1.现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那 ...