memcpy函式的實現及記憶體重疊問題的分析

2021-08-17 20:47:32 字數 2305 閱讀 5262

函式原型

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

標頭檔案

#include或#include

引數

1.memcpy中的三個引數分別為目標字串 char *dest。

2.源字串 const char *src const 這裡const是對src所指向的靜態常量區的字串常量進行修飾,保護源字串在記憶體拷貝的過程不被修改。

3.需要拷貝的位元組個數 size_t n

typedef unsigned int szie_t這裡的size_t其實就是為無符號整型unsigned int進行別名,因為在記憶體拷貝函式中,一方面拷貝的位元組數不可能是負整數,另一方面位元組數不可能是實數,出於上面兩個方面的考慮位元組數的型別應定義為size_t.

返回值

memcpy returns the value of dest. 返回目標字串的位址

函式描述記憶體重疊

注意:在這裡的記憶體重疊我們只考慮為了成功實現記憶體拷貝要排除的記憶體重疊的情況。

當然也可能出現目標字串覆蓋源字串的情況,但如果其滿足成功拷貝的條件即可。

可以把src、dest、src+n比作數軸上的三個數字,當進行記憶體拷貝是。如果dest處於src和src+n之間時,一定會出現記憶體覆蓋的現象,而且還會改變源字串的內容,進行錯誤的拷貝。因此為了能夠合理進行拷貝,提出如下的解決方案。

一.高位址向低位址進行拷貝

由於在虛擬位址空間中,棧空間的生長方向是高位址向低位址生長,首先採用這種方式。簡略的講就是源字串中的字元從前往後向目標字串按給定位元組的大小依此進行拷貝。

觀察上圖,可以得到兩個合理的區間即不會出現記憶體覆蓋的區間。

(1)dest<=src

第一種情況dest=src,此時源字串與目標字串指標指向同乙個位置,拷貝的過程相當自己給自己賦值,因此拷貝結束 後源字串並沒有發生變化。

第二種情況dest<src,這樣的拷貝儘管會覆蓋src的內容,出現了記憶體重疊,但其可以完成記憶體拷貝的功能,並沒有將錯誤的資訊拷貝過來。

由上圖可見,當dest>=src+n,無論如何都不會出現記憶體重疊的問題。

二.低位址向高位址拷貝

這種拷貝方式是為了處理,dest處於src和src+n之間,即一定會出現記憶體重疊的問題。

為了避免出現這種情況,我們可以將src和dest都移動 n-1個位置,這樣我們就可以從位址值向高位址進行拷貝,這樣儘管也有可能目標字串覆蓋源字串的情況,但是定影可以得到乙個正確的拷貝。

大家可以自行進行驗證!

memcpy函式的實現

#include

#include

#include

void *my_memcpy(char *dest,const char *src,size_t n)

}else

}return res;

}

**於網上的測試用例

void test()

;    mymemmove(p2,p1,strlen(p1)+1);

printf("%s\n",p2);

mymemmove(null,p1,strlen(p1)+1);

mymemmove(p2,null,strlen(p1)+1);

mymemmove(p1+1,p1,strlen(p1)+1);

printf("%s\n",p1);

mymemmove(p1,p1+1,strlen(p1)+1);

printf("%s\n",p1);

}

模擬實現memcpy函式(記憶體拷貝函式)

第一種 include include include void my memcpy void dest,const void src,int count return dest 返回目標空間的起始位址 void show int arr2,int arr1,int sz printf n int ...

memcpy函式的實現

前段時間去面試自己比較喜歡的乙個工作,面試的哥們讓我實現void memcpy void to,const void from,size t count 這個函式。沒做出來,掛了。感到非常不爽。回來研究了一下。找著了幾個不同版的實現,貼出來。首先對這個函式做一些說明。include void mem...

memcpy函式實現

1.原型 void memcpy void dest,const void src,size t size 標頭檔案 include 功能 由src所指記憶體區域複製size個位元組到dest所指記憶體區域。memcpy 時就需要考慮位址 重疊的情況。2.記憶體布局情況 1 源位址和目的位址不重疊 ...