博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
memmove 和 memcpy的区别以及处理内存重叠问题
阅读量:2381 次
发布时间:2019-05-10

本文共 1520 字,大约阅读时间需要 5 分钟。

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函数

memmove原型:

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*)dst;    char* 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是能正常工作的。

此文章转载自:

你可能感兴趣的文章
BOM
查看>>
Eclipse Debug调试详解
查看>>
Type Dynamic Web Module 4.0 requires Java 1.8 or newer----彻底杀死Bug
查看>>
前端接口请求测试
查看>>
error RS102 too stale to catch up
查看>>
Nagios监控MySQL报错:NRPE: Unable to read output的详细解决过程
查看>>
YUM安装调试以及命令详解
查看>>
在MySQL中使用init-connect与binlog来实现用户操作追踪记录
查看>>
使用Duplicate target database命令恢复线上oracle datagard备库
查看>>
源码编译安装MySQL5.6.12详细过程
查看>>
Emoji表情符号录入MySQL数据库报错的解决方案
查看>>
Linux系统CentOS6.2版本下安装JDK7详细过程
查看>>
Android Studio之Activity切换动画(三)
查看>>
我是怎样和Linux系统结缘并通过红帽RHCE认证的
查看>>
DIYer最担心的事来了!CPU降价彻底无望
查看>>
WannaCry勒索软件还在继续传播和感染中
查看>>
为发展中国家儿童提供的OLPC OS 13.2.10 发布
查看>>
帅的代价!无框车门冻死:特斯拉一招解决
查看>>
美银美林提高Intel科技股的股票评级
查看>>
专家预测2019年的网络安全形势
查看>>