• 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是能正常工作的。

    赐教!

  • 相关阅读:
    分布式与集群的区别是什么?
    Java NIO:IO与NIO的区别 JAVA BIO与NIO、AIO的区别
    localStorage使用总结 JS 详解 Cookie、 LocalStorage 与 SessionStorage
    tomcat+nginx+redis实现均衡负载、session共享 存储过程的优缺点 HTTP、TCP、IP协议常见面试题
    高并发下的Java数据结构(List、Set、Map)
    [剑指offer] 31. 整数中1出现的次数(从1到n整数中1出现的次数)
    [剑指offer] 30. 连续子数组的最大和
    [剑指offer] 29. 最小的K个数
    [剑指offer] 28. 数组中出现次数超过一半的数字
    [leetcode] 51. N-Queens (递归)
  • 原文地址:https://www.cnblogs.com/melons/p/5791840.html
Copyright © 2020-2023  润新知