日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

memcpy内存重叠问题

發布時間:2023/12/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 memcpy内存重叠问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

memcpy內存重疊

之前一直沒有注意到內存復制函數的內存重疊問題。今天偶遇遂琢磨了一下,記之。

函數簡介:c和c++使用的內存拷貝函數,memcpy函數的功能是從源src所指的內存地址的起始位置開始拷貝n個字節到目標dest所指的內存地址的起始位置中。一般避免內存重疊。

沒有內存重疊的情況:

void *mymemcpy(void *dst,const void *src,size_t num) { if(NULL == dst || NULL == src){ return NULL; } //assert((dst !=NULL) && (src!=NULL));if(dst>=src+num||src>dst+num){ char * psrc = (char *)src;char * pdst = (char *)dst; while(num-->0)*pdst++ = *psrc++; } return dst; }

出現內存重疊的情況

void * mymemcpy(void *dst, const void *src, size_t count) { if (dst== NULL || src == NULL) return NULL; char *pdest = (char *)(dst); const char *psrc = (char *)(psrc); int n = count; //pdest地址高于psrc地址,且有重疊if (pdest > psrc && pdest < psrc+count) { for (size_t i=n-1; i != -1; --i) { pdest[i] = psrc[i];//從高到低賦值 } } //pdest地址低于psrc地址,且有重疊else if(pdest < psrc && pdest > psrc-count){ for (size_t i= 0; i < n; i++) { pdest[i] = psrc[i];//從低到高賦值 } } return dst; }

附錄:關于memmove,memcpy

1.memmove
函數原型:void *memmove(void *dest, const void *source, size_t count)
返回值說明:返回指向dest的void *指針
參數說明:dest,source分別為目標串和源串的首地址。count為要移動的字符的個數
函數說明:memmove用于從source拷貝count個字符到dest,如果目標區域和源區域有重疊的話,memmove能夠保證源串在被覆蓋之前將重疊區域的字節拷貝到目標區域中(此時源字符串尾部字符改變)。
2.memcpy
函數原型:void *memcpy(void *dest, const void *source, size_t count);
返回值說明:返回指向dest的void *指針
函數說明:memcpy功能和memmove相同,但是memcpy中dest和source中的區域不能重疊,否則會出現未知結果。
3.兩者區別
函數memcpy() 從source 指向的區域向dest指向的區域復制count個字符,如果兩數組重疊,不定義該函數的行為。
而memmove(),如果兩函數重疊,賦值仍正確進行。
memcpy函數假設要復制的內存區域不存在重疊,如果你能確保你進行復制操作的的內存區域沒有任何重疊,可以直接用memcpy;
如果你不能保證是否有重疊,為了確保復制的正確性,你必須用memmove。
memcpy的效率會比memmove高一些,兩者的實現:

void* memmove(void* dest, void* source, size_t count) { assert((dest!=NULL) && (source !=NULL)); void* ret = dest; if (dest <= source || dest >= (source + count)) { while (count --) *dest++ = *source++; } else { dest += count - 1; source += count - 1; while (count--) *dest-- = *source--;} return ret; }void* memcpy(void* dest, void* source, size_t count) { assert((dest!=NULL) && (source !=NULL)); void* ret = dest; while (count--) *dest++ = *source; return ret; }

對于字符串拷貝函數,strcpy()也是存在內存重疊問題的。

總結

以上是生活随笔為你收集整理的memcpy内存重叠问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。