1. 程式人生 > >strcpy及memcpy的記憶體重疊處理

strcpy及memcpy的記憶體重疊處理

strcpy和memcpy同是一個型別的函式,但實質上卻是不同的,他們的原型分別為: char *strcpy(char *dest, const char *src);void *memcpy(void *dest, const void *src, size_t count);當我們使用這兩個函式時都會出現同樣一個問題,記憶體重疊。那麼我們就來分析一下記憶體重疊是如何產的。現在假設有char *d = dest;  char *s = src;要複製count = 5個字元,如下圖所示:       1、第一種情況為 d <= s; 這種情況為d在s的後面,將s指向的東西往d指向的地方複製,d與s往後移動時內容互不干擾這是一種正常的狀態。      2、第二種情況為d >= s + count; 這種情況是要複製的內容在兩指標之間,此時指標移動時也不會對要複製的內容產生干擾,也不存在內重疊現象。        3、第三種情況時要複製的內容要比兩指標的間距長,並且是由s往d中複製,如下圖所示:
    我們看到最後的結果變成了"hellh"而不是我們想要得到的"hello",於是,這就是產生記憶體重疊後的結果。解決記憶體重疊問題時我們可以將兩個指標同時向後移動count-1個位元組大小,讓s指向要複製的最後一個元素的首地址,從後往前複製,如下圖:這樣的處理後就能得到我們先要的結果了。下面時具體的程式碼實現。void *memcpy(void *dest, constvoid *src,int count){       assert(dest != NULL);       assert(src != NULL);        char *d = dest;       char *s = src;          if(d <= s || d >= s + count)        {               while(count)               {                      *d = *s;                        d++;                         s++;                        count--;                }         }         else         {                d += count - 1;                s += count -1;                while(count)                {                         *d = *s;                          d++;                          s++;                          count--;                }         }       return dest;}(strcpy與之很相似,在這我就不寫程式碼了)這就是記憶體重疊的處理方法。  當使用記憶體拷貝函式拷貝內容到新空間時我們會發現最後的結果會出現這樣的東西:“
”這是由於我們沒有將'\0'給拷貝過去。指標會根據首地址尋找到原來首地址後邊的東西,但當指標遇到'\0'時就停止定址,所以要解決上述問題只需在最後加上'\0'即可。