memcpy函數和memmove函數的區別

前言:今天在學習過程中的看到一個memmove函數,於是就想知道這個函數具體功能是什麼呢。



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




區別:當存在重疊(overlapping)內存塊時,memmove函數可以正確拷貝結果;而memcpy則不保證結果正確(拷貝結果可能正確也有可能是錯誤的)。

如下圖所示兩種情況:
(一)第一種情況下(dst<=src || dst > = src _+ count ),有重疊的區域進行拷貝時也不會出現問題,即內容均可以被正確的拷貝;
(二)第二種情況下(dst > src),重疊的區域進行拷貝時會出現問題,紅色重疊部分的兩個字節,原先src的內容已被覆蓋,且未被保存。使得  之後拷貝的時候,實際上拷貝的是已經被覆蓋的內容。
















針對以上情況,memmove函數的處理方法:
(一)當源內存的首地址大於目的內存的首地址或者目的內存的首地址大於源內存包括要拷貝的內存塊後的尾地址(dst<=src || dst > = src _+ count )時,實行正向拷貝(即同memcpy函數的處理方式一致);
(二)當源內存的首地址小於目的內存的首地址時,以防重疊部分拷貝出錯,則實行反向拷貝

__________________________________________________________________________________________________________________________________

兩個函數的實現代碼:
void * memcpy ( void * dst,const void * src,size_t count)

{

         void * ret = dst;

         while (count--)

         { // 注意, memcpy函數沒有處理dst和src區域是否重疊的問題

                   *(char *)dst = *(char *)src;

                   dst = (char *)dst + 1;

                   src = (char *)src + 1;

                 //也可以用 *dst++ = *src++;語句替換上面三條語句

         }

         return(ret);

}

void *memmove(void*dst, const void*src, size_t count)
{
     void *ret = dst;
     if(dst < = src || dst >= src + count)
       {
                   // 若dst和src區域沒有重疊,則從起始處開始逐一拷貝

                   while (count--)

                   {

                            *(char *)dst = *(char *)src;

                            dst = (char *)dst + 1;

                            src = (char *)src + 1;

                   }

                   else

                      { // 若dst和src 區域交叉,則從尾部開始向起始位置拷貝,這樣可以避免數據衝突

                             dst = (char *)dst + count - 1;

                             src = (char *)src + count - 1;

                             while (count--)

                              {

                                       *(char *)dst = *(char *)src;

                                        dst = (char *)dst - 1;

                                        src = (char *)src - 1;

                                        //或者用 *dst-- = *src--;替換上面三條語句

                                 }

         }

         return(ret);

       }
}



------------------------------------------------------------------------------------------------------------------------------------------------

特此感謝以下參考來源:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章