標籤:des blog http strong 檔案 os
函數原型:
void *memcpy( void *dest, const void *src, size_t count );void *memmove( void* dest, const void* src, size_t count );
1.memcpy和memmove相同點
都是用於從src拷貝count個位元組到dest。
2.memcpy和memmove區別
如果目的地區域和來源區域有重疊的話:
memcpy不能夠確保源串所在重疊地區在拷貝之前被覆蓋。
memmove能夠保證源串在被覆蓋之前將重疊地區的位元組拷貝到目的地區域中,複製後src內容會被更改,當目的地區域與來源區域沒有重疊則和memcpy函數功能相同。
但當源記憶體和目標記憶體存在重疊時,memcpy會出現錯誤,而memmove能正確地實施拷貝,但這也增加了一點點開銷。
memmove的處理措施:
(1)當源記憶體的首地址等於目標記憶體的首地址時,不進行任何拷貝
(2)當源記憶體的首地址大於目標記憶體的首地址時,實行正向拷貝
(3)當源記憶體的首地址小於目標記憶體的首地址時,實行反向拷貝
3.Linux下的實現過程
linux下,兩個函數都在標頭檔string.h中定義,函數原型為:
void * __cdecl memcpy ( void * dst,const void * src,size_t count);void * __cdecl memmove ( void * dst,const void * src,size_t count); //實現代碼如下:void * __cdecl 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; } return(ret);} void * __cdecl memmove ( void * dst,const void * src,size_t count){ void * ret = dst; if (dst <= src || (char *)dst >= ((char *)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; } } return(ret);}
當src和dst地區沒有重疊時,兩個函數是完全一樣的。否則,memcpy不能正常工作的,memmove是可以正常工作的。
4.Windows平台
#include <stdio.h>#include <string.h>/* VS2010, Windows XP, Debug模式下運行 */int main(void){ void test_memfunc(void);test_memfunc();return 0;}void test_memfunc(void){char s1[] = "abcdefgefghijklmnopq";//首地址:0x0012ff48char s2[] = "123456789";//首地址:0x0012ff34char *c = NULL;int l = sizeof(s1);//數組s1長度為21 /* 記憶體重疊 : s2覆蓋了原s1()的一部分空間。 即: s2(0x0012ff34-0x0012ff49)的記憶體位址範圍和s1(0x0012ff48-0x0012ff5c)的記憶體位址範圍發生重疊 */ c = memcpy(s2,s1,sizeof(s1));//改用memmove同樣運行出錯 /* 運行出錯:變數s1損壞。 Run-Time Check Failure #2 - Stack around the variable ‘s2‘ was corrupted. */ printf("%s",s1);}
windows平台下,當發生記憶體重疊的時候,都不能正常運行,運行棧被破壞,提示錯誤:Run-Time Check Failure #2 - Stack around the variable ‘s2‘ was corrupted.
參考:
http://msdn.microsoft.com/en-us/magazine/cc301374.aspx
http://www.cnblogs.com/BeyondAnyTime/archive/2012/05/10/2495013.html