c++——内存重叠问题

1. 问题引入

内存覆盖情况1(会改变src内存的值,如再操作src,将会有出错的风险):

内存覆盖情况2(拷贝最后两个字节时,src中的内存已经发生改变):

2. memcpy

2.1 原型

void *memcpy(void *dest, const void *src, size_t n);

描述:memcpy()函数从src内存中拷贝n个字节到dest内存区域,但是源和目的的内存区域不能重叠。

返回值说明:返回指向dest的void *指针

2.2 实现

void* MyMemcpy(void* dst, const void* src, size_t n)
{
    char *tmp = (char*)dst;
    char *s_src = (char*)src;
 
    while(n--) {
        *tmp++ = *s_src++;
    }

    return dst;
}

这种方式会导致如上图中内存覆盖情况2中所示,当拷贝最后两个字节的时候src中的内容已经改变。

3. memmove

3.1 原型

void *memmove(void *dest, const void *src, size_t n);

描述:memmove用于从source拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中(此时源字符串尾部字符改变)。

返回值说明:返回指向dest的void *指针

3.2 实现

void* MyMemmove(void* dst, void* src, size_t n) 
{ 
    if((nullptr == dst) || (nullptr == src))
    {
        return nullptr;
    }    

    void* tmp= dst; 
    if (dst <= src || dst>= (src + n))  //此时无需考虑内存重叠
    { 
        while (n--) 
           *dst++ = *src++; 
    } 
    else 
    { 
        dst+= n- 1; 
        src+= n- 1; 
        while (n--) 
           *dst-- = *src--;  //倒序拷贝
   } 
      
   return tmp; 
}

4. 扩展

1)memcpy的效率比memmove略高;

2)字符串拷贝函数strcpy同样存在内存重叠的问题;

猜你喜欢

转载自blog.csdn.net/www_dong/article/details/114556248