[整理]記憶體重疊之memcpy、memmove

來源:互聯網
上載者:User

標籤: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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.