博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
memcpy函数和memmove函数实现的区别
阅读量:2383 次
发布时间:2019-05-10

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

原文转载地址:

一、memmove()和memcpy()函数和strcpy()函数的区别;

(1)使用的类型不同,strcpy()函数只对字符串进行操作;memmove()和memcpy()函数对所有类型都适用,为内存拷贝;

(2)strcpy()以’\0’为拷贝的结束条件;而memmove()和memcpy()函数则是以第三个参数num进行控制拷贝;
二、函数说明:

1.memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝N个字节到目标dst所指的内存地址的起始位置中。

2.memmove函数的功能同memcpy基本一致,但是当src区域和dst内存区域重叠时,memcpy可能会出现错误,而memmove能正确进行拷贝
三、memmove()和memcpy()函数的区别和联系:

相同点: 两个都是内存拷贝,对所有类型都适用;

不同点:
(1)memcpy()函数是从前往后拷贝;假入出现内存重叠的现象;拷贝结果可能出错;
(2)memmove()函数在memcpy()函数的基础上加入了对内存重叠拷贝的处理;引入了倒序拷贝的方式处理内存重叠的某些情况;保证拷贝的正确性;

综上:在现实中使用memmove()函数会比较好一点;

四、各种拷贝情况:

这里写图片描述

上述三种情况,memcpy可以成功对前两种进行拷贝,对第三种情况进行拷贝时,由于拷贝dst前两个字节时覆盖了src原来的内容,所以接下来的拷贝会出现错误。而memmove对第三种情况进行拷贝时会从src的最后向前拷贝N个字节,避免了覆盖原来内容的过程。
五、模拟实现:
memcpy:

//模式实现memcpy(不会解决内存重叠的问题,正序拷贝,适用于任何类型)

void* MyMemcpy(void* dest,const void* src,size_t num)
{
     char* dest_tmp=(char*)dest;//目标字符串
     const char* src_tmp=(const char*)src;//源字符串
     assert(dest&&src);
     while(num--)
     {
         *dest_tmp++= *src_tmp++;
     }
     return dest;
}

    1

    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

memmove:

//模拟实现memove(会解决内存重叠的问题,加上了逆序拷贝,适用于任何类型)

void* MyMemmove(void* dest,const void* src,size_t num)
{
    char* dest_tmp=(char*)dest;
    const char* src_tmp=(const char*)src;
    assert(dest&&src);
    if (src_tmp>dest_tmp || src_tmp+num<=dest_tmp)//情况1和情况2
    {
        while(num--)//正序复制
        {
            *dest_tmp++=*src_tmp++;
        }
    }
    else//情况3,逆序赋值
    {
        //调整指针到最后
        dest_tmp+=num-1;
        src_tmp+=num-1;
        while(num--)
        {
            *dest_tmp--=*src_tmp--;
        }
    }
    return dest;
}
 

strcpy函数的实现过程:

char *strcpy(char *strDest, const char *strSrc) // 实现strSrc到strDest的复制

{
    if ((strDest == NULL) || (strSrc == NULL)) //判断参数strDest和strSrc的有效性
    {
        return NULL;
    }
 
    char *strDestCopy = strDest; //保存目标字符串的首地址
    while ((*strDest++ = *strSrc++)!='\0'); //把strSrc字符串的内容复制到strDest下

//这里注意先执行完赋值语句,因为在小括号里面,也就是先将\0拷贝到目的地址中去,然后进行判断,跳出while循环,也就是将整个字符串+\0进行拷贝。

 
    return strDestCopy;
}

你可能感兴趣的文章
Linux内核和用户空间通信的方式— proc文件和mmap共享内存
查看>>
基于DSP/BIOS和NDK的嵌入式网络操作系统设计方案
查看>>
CCS开发环境搭建小结
查看>>
DM642 gel文件和.cmd文件参考
查看>>
DSP软件优化小实验
查看>>
DSP/BIOS 介绍
查看>>
多线程编程之重点--使用DSP/BIOS时选择线程类型的参考方法
查看>>
DSP/BIOS在嵌入式数据采集系统中的应用
查看>>
基于DSP/BIOS和NDK的嵌入式网络操作系统设计方案
查看>>
迅雷C++试题及解答
查看>>
Linux 中断学习之小试牛刀篇
查看>>
中断之原理篇
查看>>
高内聚 低耦合
查看>>
GUI开发之DirectFB
查看>>
GTK/DirectFB两个闪烁的问题
查看>>
《Linux内核修炼之道》 之 高效学习Linux驱动开发
查看>>
编写可移植C/C++程序的要点
查看>>
DirectFB代码导读
查看>>
linux fork函数浅析
查看>>
内核启动时间优化
查看>>