memmove和memcpy函式的區別及實現

gogogo_sky發表於2017-05-21

一、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;
}

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;
}

相關文章