http://blog.csdn.net/caowei840701/article/details/8491836
[cpp]?view plain?copy
- <p>??
- 關于memcpy和memmove兩個c標準庫函數,其功能都是將一塊內存區域中的指定大小內容復制到目標內存中,在翻閱c標準庫實現的源代碼我們發現他們是有區別的。</p><p>首先看memcpy的實現:</p><p>?</p>??
[cpp]?view plain?copy
- void?*?__cdecl?memcpy?(??
- ????????void?*?dst,??
- ????????const?void?*?src,??
- ????????size_t?count??
- ????????)??
- {??
- ????????void?*?ret?=?dst;??
- ??
- #if?defined?(_M_MRX000)?||?defined?(_M_ALPHA)?||?defined?(_M_PPC)??
- ????????{??
- ????????extern?void?RtlMoveMemory(?void?*,?const?void?*,?size_t?count?);??
- ??
- ????????RtlMoveMemory(?dst,?src,?count?);??
- ????????}??
- #else??/*?defined?(_M_MRX000)?||?defined?(_M_ALPHA)?||?defined?(_M_PPC)?*/??
- ????????/*?
- ?????????*?copy?from?lower?addresses?to?higher?addresses?
- ?????????*/??
- ????????while?(count--)?{??
- ????????????????*(char?*)dst?=?*(char?*)src;??
- ????????????????dst?=?(char?*)dst?+?1;??
- ????????????????src?=?(char?*)src?+?1;??
- ????????}??
- #endif??/*?defined?(_M_MRX000)?||?defined?(_M_ALPHA)?||?defined?(_M_PPC)?*/??
- ??
- ????????return(ret);??
- }??
再看memmove的實現:
[cpp]?view plain?copy
- void?*?__cdecl?memmove?(??
- ????????void?*?dst,??
- ????????const?void?*?src,??
- ????????size_t?count??
- ????????)??
- {??
- ????????void?*?ret?=?dst;??
- ??
- #if?defined?(_M_MRX000)?||?defined?(_M_ALPHA)?||?defined?(_M_PPC)??
- ????????{??
- ????????extern?void?RtlMoveMemory(?void?*,?const?void?*,?size_t?count?);??
- ??
- ????????RtlMoveMemory(?dst,?src,?count?);??
- ????????}??
- #else??/*?defined?(_M_MRX000)?||?defined?(_M_ALPHA)?||?defined?(_M_PPC)?*/??
- ????????if?(dst?<=?src?||?(char?*)dst?>=?((char?*)src?+?count))?{??
- ????????????????/*?
- ?????????????????*?Non-Overlapping?Buffers?
- ?????????????????*?copy?from?lower?addresses?to?higher?addresses?
- ?????????????????*/??
- ????????????????while?(count--)?{??
- ????????????????????????*(char?*)dst?=?*(char?*)src;??
- ????????????????????????dst?=?(char?*)dst?+?1;??
- ????????????????????????src?=?(char?*)src?+?1;??
- ????????????????}??
- ????????}??
- ????????else?{??
- ????????????????/*?
- ?????????????????*?Overlapping?Buffers?
- ?????????????????*?copy?from?higher?addresses?to?lower?addresses?
- ?????????????????*/??
- ????????????????dst?=?(char?*)dst?+?count?-?1;??
- ????????????????src?=?(char?*)src?+?count?-?1;??
- ??
- ????????????????while?(count--)?{??
- ????????????????????????*(char?*)dst?=?*(char?*)src;??
- ????????????????????????dst?=?(char?*)dst?-?1;??
- ????????????????????????src?=?(char?*)src?-?1;??
- ????????????????}??
- ????????}??
- #endif??/*?defined?(_M_MRX000)?||?defined?(_M_ALPHA)?||?defined?(_M_PPC)?*/??
- ??
- ????????return(ret);??
- }??
仔細分析上面的代碼不難看出,memcpy只是簡單的將兩塊內存區域當作沒有關系的相互獨立內存區域進行內存的拷貝,而memmove則考慮了當兩塊內存區域有重疊時所采用不同方向的拷貝模式進行處理。
如上圖所示,當源內存和目標內存出于第一種情況即兩塊內存區域相互獨立時,memcpy和memmove都是可以正確處理的。在第二種情況下,兩個函數都可以正常的實現內存拷貝。而當兩塊內存區域處于第三種情況時,很明顯memcpy的實現存在問題,當將源內存塊的開始字節拷貝到目標內存時,同時也會覆蓋源內存塊中的尚未拷貝的內存,導致從源內存在目標內存地址處開始的內存不能正確的拷貝。
?