程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 我不知道的memcpy和memmove

我不知道的memcpy和memmove

編輯:關於C語言
 

變態的命名

我們在寫程序時,一般講究見到變量的命名,就能讓別人基本知道該變量的含義。memcpy內存拷貝,沒有問題;memmove,內存移動?錯,如果這樣理解的話,那麼這篇文章你就必須要好好看看了,memmove還是內存拷貝。那麼既然memcpy和memmove二者都是內存拷貝,那二者究竟有什麼區別呢?

先說memcpy

你有沒有好好的參加過一場C++筆試。讓你寫出memcpy的實現,這是多麼常見的筆試題啊。現在,拿起你的演算紙和筆;是的,是筆和紙,不是讓你在你的IDE上寫。寫不出來?看下面吧:

void *mymemcpy(void *dest, const void *src, size_t count){
    assert(dest != NULL && src != NULL);
    
    char *tmp = (char *)dest;
    char *p = (char *)src;

    while (count--)
    {
        *tmp++ = *p++;
    }
    return dest;}

memcpy的實現很簡單,一般在筆試時,出現寫源碼的題目,無非就是需要注意以下幾點:

  1. 確定函數原型;
  2. 判斷參數合法性;
  3. 邏輯實現(考慮各種情況,統稱邏輯實現);
  4. 錯誤處理。

當然了,我的這個沒有錯誤處理,也不需要錯誤處理。上面,我寫出了memcpy的實現源碼,實現原理如下圖所示:
果凍想 | 一個原創文章分享網站

這樣下去,上面的代碼會運行的很好,如果出現下面的情況呢?
果凍想 | 一個原創文章分享網站

i、n、k的內存和J、e、l的內存地址重合了,現在再使用上面的代碼進行copy時,會出現什麼問題呢?你有沒有想過這個問題。如果沒有,那就現在想想,不急著閱讀下面的內容。

然後,我再留一個問題,上面的代碼中,為什麼都需要將void *轉換成char *呢?比如:

char *tmp = (char *)dest;

可以留言回答哦。

再說memmove

memmove也是用來實現內存的直接拷貝的。說起這個命名,我個人覺的多少還是有點坑的。既然memmove也是用來內存數據移動的,那就先來看看memmove的實現源碼。

void *mymemmove(void *dest, const void *src, size_t count){
    assert(dest != NULL && src != NULL)

    if (dest < src)
    {
        char *p = (char *)dest;
        char *q = (char *)src;
        while (count--)
        {
            *p++ = *q++;
        }
    }
    else
    {
        char *p = (char *)dest + count;
        char *q = (char *)src + count;
        while (count--)
        {
            *--p = *--q;
        }
    }

    return dest;}

從源碼看,memmove的確比memcpy復雜一些;再仔細一看,多了些什麼?哦,多了一個else分支,而正是這個else分支,就處理了當src和dest的內存重合的問題。

memcpy和memmove的比較

從實現源碼中的確能看出一些貓膩,當出現了src和dest的內存有重合的時機時,memmove的處理規則是從後往前進行copy。當然了,重合的問題,需要考慮的以下兩種場合。
果凍想 | 一個原創文章分享網站

如圖所示,當出現(1)對應的情況時,就需要先從src的頭部開始復制;也就是memmove源碼中的if分支,這部分源碼和memcpy的實現是一致的;當出現(2)對應的情況時,就需要先從src的尾部開始復制,防止出現了覆蓋現象。這就是memmove比memcpy多的一個考慮點,所以說,在實際使用時,使用memmove是比memcpy更安全的。

總結

總結到了這裡,我覺的我已經把問題說清楚了。你說呢?如果你還有什麼好的想法,歡迎你和我分享。

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved