memcpy與memmove都是C語言的庫函數(shù),在頭文件string.h中,作用是內(nèi)存拷貝。唯一的區(qū)別是,當內(nèi)存發(fā)生局部重疊時,memmove保證了拷貝的結(jié)果是正確的,但是memcopy不一定是正確的。但是memcpy比memmove速度快。
成都創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的陽原網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!void * memcpy ( void * destination, const void * source, size_t num );
void * memmove ( void * destination, const void * source, size_t num );
destination即目標空間,即要復(fù)制到哪個空間
source即源空間,即要被復(fù)制的內(nèi)存空間
num即要復(fù)制多少個字節(jié)的內(nèi)容到destination
void*即返回目標空間
這是對memcpy和memmove函數(shù)的聲明,可以明確看出,其返回的是void*類型的指針,并且有三個參數(shù),第一個參數(shù)表示目標地址,第二個參數(shù)表示源地址,第三個參數(shù)表示拷貝大小(單位是字節(jié))。此函數(shù)代表著,在內(nèi)存空間中,從source指向的空間開始,往后一共num個字節(jié)的內(nèi)存空間,將這些空間里面的內(nèi)容拷貝到 從destination指向的空間開始,往后一共num個字節(jié)的內(nèi)存空間。
2.memcpy代碼實現(xiàn)void* my_memcpy(void* dest, const void* src, size_t count) {
assert(dest && src);
void* ret = dest;
while (count--) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
3.memmove代碼實現(xiàn)void* my_memmove(void* dest, const void* src, size_t count) {
assert(dest && src);
void* ret = dest;
if (dest< src) {
while (count--) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else {
dest = (char*)dest + count - 1;
src = (char*)src + count - 1;
while (count--) {
*(char*)dest = *(char*)src;
dest = (char*)dest - 1;
src = (char*)src - 1;
}
}
return ret;
}
4.內(nèi)存拷貝原則首先將void*強制轉(zhuǎn)換成char*;其次一個字節(jié)一個字節(jié)拷貝內(nèi)存;然后指向目標空間和源空間地址的指針每次往后走一個字節(jié)的位置,循環(huán)拷貝相應(yīng)的字節(jié)數(shù)即可。
5.拷貝情況分類1)兩塊不同的內(nèi)存,memcpy和memmove拷貝結(jié)果一致。
2)內(nèi)存重疊,分為兩種情況。如下圖所示:
代碼驗證三種情況如下:
#include#includeint main()
{
char szdes[40];
char szsrc[] = "Pierre de Fermat";
memcpy(szdes, szsrc, strlen(szsrc) + 1);//+1是因為要拷貝\0
printf("%s\n",szdes);
int arr1[10] = {0};
int arr2[5] = {4,2,55,88,3};
memcpy(arr1+3, arr2, sizeof(arr2)); //arr1是 arr1[10]這個數(shù)組首元素的地址,+3就是跳過3個int類型的數(shù)據(jù)
for (int i = 0;i< 10;i++)
printf("%d, ", arr1[i]);
printf("\n");
int arr3[10] = {1,2,3,4,5,6,7,8,9,10};
memcpy(arr3, arr3+2, 5*sizeof(int));
for (int i = 0;i< 10;i++)
printf("%d, ", arr3[i]);
printf("\n");
int arr4[10] = {1,2,3,4,5,6,7,8,9,10};
memmove(arr4, arr4+2, 5*sizeof(int));
for (int i = 0;i< 10;i++)
printf("%d, ", arr4[i]);
printf("\n");
int arr5[10] = {1,2,3,4,5,6,7,8,9,10};
memcpy(arr5+2, arr5, 5*sizeof(int));
for (int i = 0;i< 10;i++)
printf("%d, ", arr5[i]);
printf("\n");
int arr6[10] = {1,2,3,4,5,6,7,8,9,10};
memmove(arr6+2, arr6, 5*sizeof(int));
for (int i = 0;i< 10;i++)
printf("%d, ", arr6[i]);
printf("\n");
return 0;
}
window上vs輸出結(jié)果為:
linux 輸出結(jié)果為:
6.總結(jié)1)szsrc拷貝到szdes 上(arr2拷貝到arr1上),由于兩塊不同的內(nèi)存塊,memcpy和memmove功能一樣,拷貝正確。
2)arr3和arr4,由于dest的指針地址在src的地址前面,且拷貝是一個字節(jié)一個字節(jié)的拷貝,雖然有局部內(nèi)存重疊,但是按照從前往后拷貝的原則,其覆蓋內(nèi)容是舊空間的內(nèi)容,memcpy和mommove的拷貝都是正確的。
3)arr5和arr6,由于dest的指針地址在src的地址后面,這種情況下,memcpy拷貝可能會存在錯誤,memmove拷貝正確。如上兩圖的輸出結(jié)果可以看出,相同代碼在不同環(huán)境下,其數(shù)據(jù)的內(nèi)容不一致。此種拷貝linux的運行結(jié)果錯誤。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧