memcpy内存重叠问题
memcpy內存重疊
之前一直沒有注意到內存復制函數的內存重疊問題。今天偶遇遂琢磨了一下,記之。
函數簡介:c和c++使用的內存拷貝函數,memcpy函數的功能是從源src所指的內存地址的起始位置開始拷貝n個字節(jié)到目標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,如果目標區(qū)域和源區(qū)域有重疊的話,memmove能夠保證源串在被覆蓋之前將重疊區(qū)域的字節(jié)拷貝到目標區(qū)域中(此時源字符串尾部字符改變)。
2.memcpy
函數原型:void *memcpy(void *dest, const void *source, size_t count);
返回值說明:返回指向dest的void *指針
函數說明:memcpy功能和memmove相同,但是memcpy中dest和source中的區(qū)域不能重疊,否則會出現未知結果。
3.兩者區(qū)別
函數memcpy() 從source 指向的區(qū)域向dest指向的區(qū)域復制count個字符,如果兩數組重疊,不定義該函數的行為。
而memmove(),如果兩函數重疊,賦值仍正確進行。
memcpy函數假設要復制的內存區(qū)域不存在重疊,如果你能確保你進行復制操作的的內存區(qū)域沒有任何重疊,可以直接用memcpy;
如果你不能保證是否有重疊,為了確保復制的正確性,你必須用memmove。
memcpy的效率會比memmove高一些,兩者的實現:
對于字符串拷貝函數,strcpy()也是存在內存重疊問題的。
總結
以上是生活随笔為你收集整理的memcpy内存重叠问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flutter 动态加载自定义字体
- 下一篇: NumPy 笔记(超级全!收藏√)