C++中strcpy和memcpy的區(qū)別小結(jié)
在 C++ 中,strcpy 和 memcpy 是兩個用于數(shù)據(jù)拷貝的函數(shù),但它們的設(shè)計目標、行為邏輯和適用場景有顯著差異。以下從多個維度詳細對比兩者的區(qū)別:
1. 功能定位與核心邏輯
strcpy:
全稱為 “string copy”,專門用于拷貝 C 風(fēng)格字符串(以\0結(jié)尾的字符數(shù)組)。
其核心邏輯是:從源字符串src逐字符拷貝到目標地址dest,直到遇到src的終止符\0,并將\0也拷貝到dest中(因此目標字符串會被正確終止)。函數(shù)原型:
char* strcpy(char* dest, const char* src);
memcpy:
全稱為 “memory copy”,用于拷貝任意類型的內(nèi)存塊(不僅限于字符串)。
其核心邏輯是:從源內(nèi)存地址src拷貝count字節(jié)到目標地址dest,不關(guān)心內(nèi)存中的具體內(nèi)容(無論是否包含\0或其他特殊字符)。函數(shù)原型:
void* memcpy(void* dest, const void* src, size_t count);
2. 終止條件與拷貝長度
strcpy:
拷貝長度由源字符串的\0位置決定。例如:char src[] = "Hello"; // 實際存儲為 'H','e','l','l','o','\0'(6字節(jié)) char dest[10]; strcpy(dest, src); // 拷貝6字節(jié)(包括 '\0')
若源字符串未正確以
\0結(jié)尾(如字符數(shù)組未初始化),strcpy會越界拷貝直到遇到內(nèi)存中的隨機\0,導(dǎo)致未定義行為。memcpy:
拷貝長度由用戶顯式指定的count決定。例如:int src[] = {1, 2, 3}; // 3個int,假設(shè)int占4字節(jié),共12字節(jié) int dest[3]; memcpy(dest, src, sizeof(src)); // 拷貝12字節(jié)(精確控制)即使源內(nèi)存中包含
\0,memcpy仍會拷貝所有count字節(jié)(不會提前終止)。
3. 數(shù)據(jù)類型與適用場景
strcpy:
僅適用于 C 風(fēng)格字符串(字符數(shù)組且以\0結(jié)尾)。若用于非字符串數(shù)據(jù)(如二進制數(shù)據(jù)、結(jié)構(gòu)體),會因\0提前終止導(dǎo)致拷貝不完整。典型場景:拷貝字符串變量、初始化字符串緩沖區(qū)等。例如:
char name[20]; strcpy(name, "Tom"); // 正確拷貝字符串(包含 '\0')
memcpy:
適用于 任意類型的內(nèi)存塊(如整數(shù)、結(jié)構(gòu)體、數(shù)組、二進制數(shù)據(jù)等)。只要用戶能正確計算count(字節(jié)數(shù)),就可以安全拷貝。典型場景:拷貝非字符串數(shù)據(jù)(如結(jié)構(gòu)體實例、二進制文件內(nèi)容)、批量初始化內(nèi)存等。例如:
struct Person { int age; char name[10]; }; Person src = {20, "Alice"}; Person dest; memcpy(&dest, &src, sizeof(Person)); // 完整拷貝結(jié)構(gòu)體所有成員
4. 安全性與邊界檢查
strcpy:
不檢查目標緩沖區(qū)大小。若目標dest的空間不足(小于源字符串長度 +1),會導(dǎo)致緩沖區(qū)溢出(數(shù)據(jù)覆蓋到相鄰內(nèi)存),引發(fā)程序崩潰或安全漏洞(如被惡意利用)。示例風(fēng)險:
char src[100] = "A very long string..."; char dest[10]; strcpy(dest, src); // 溢出!dest只有10字節(jié),無法容納長字符串
memcpy:
同樣不自動檢查目標緩沖區(qū)大小,但用戶需顯式指定count。若count超過目標緩沖區(qū)容量,仍會導(dǎo)致溢出。但優(yōu)勢是:用戶可通過sizeof等方式精確計算count,降低錯誤概率(需人為保證正確性)。示例安全用法:
char src[100] = "A very long string..."; char dest[10]; memcpy(dest, src, sizeof(dest)-1); // 僅拷貝9字節(jié)(預(yù)留1字節(jié)給 '\0') dest[9] = '\0'; // 手動補終止符(非字符串場景無需此操作)
5. 性能與實現(xiàn)優(yōu)化
strcpy:
因依賴 \0 終止,需逐字符檢查,效率較低(尤其對長字符串)。編譯器可能優(yōu)化為按字(如4字節(jié)或8字節(jié))拷貝,但受限于 \0 的位置,無法完全發(fā)揮內(nèi)存帶寬。memcpy:
通常優(yōu)化為按機器字長(如64位)批量拷貝(如使用 movq 指令),對大內(nèi)存塊效率更高。例如,拷貝 1024 字節(jié)時,memcpy 可能分 128 次(每次 8 字節(jié))完成,而 strcpy 需 1024 次逐字節(jié)操作。
總結(jié):如何選擇?
| 維度 | strcpy | memcpy |
|---|---|---|
| 功能 | 僅拷貝 C 風(fēng)格字符串(含 \0) | 拷貝任意類型的內(nèi)存塊(字節(jié)級) |
| 終止條件 | 依賴源字符串的 \0 | 依賴用戶指定的 count |
| 適用場景 | 字符串拷貝(需自動處理 \0) | 非字符串數(shù)據(jù)、二進制數(shù)據(jù)拷貝 |
| 安全性 | 易溢出(無大小檢查) | 需用戶保證 count 正確性 |
| 效率 | 較低(逐字符檢查 \0) | 較高(批量字拷貝) |
注意事項
- 避免 strcpy 的不安全用法:優(yōu)先使用 strncpy(需手動補 \0)或 C++ 的 std::string(自動管理內(nèi)存)。
- memcpy 的正確使用:確保 count 不超過目標緩沖區(qū)容量,且源和目標內(nèi)存無重疊(若重疊需用 memmove)。
到此這篇關(guān)于C++中strcpy和memcpy的區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)C++ strcpy memcpy內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Opencv3.4.0實現(xiàn)視頻中的幀保存為圖片功能
這篇文章主要為大家詳細介紹了Opencv3.4.0實現(xiàn)視頻中的幀保存為圖片功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05
C++實現(xiàn)LeetCode(173.二叉搜索樹迭代器)
這篇文章主要介紹了C++實現(xiàn)LeetCode(173.二叉搜索樹迭代器),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08
UE4 Unlua 調(diào)用異步藍圖節(jié)點AIMoveTo函數(shù)示例詳解
這篇文章主要為大家介紹了UE4 Unlua 調(diào)用AIMoveTo函數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
C++ 時間庫duration 類的原理與復(fù)現(xiàn)(最新整理)
本文解析了C++11 chrono庫中duration類的實現(xiàn)原理,基于ratio模板實現(xiàn)時間間隔的類型化表示,通過編譯期計算和類型安全設(shè)計支持靈活的時間單位轉(zhuǎn)換與算術(shù)運算,對比了標準庫與自定義實現(xiàn)的差異,強調(diào)了模板元編程在時間處理中的優(yōu)勢,感興趣的朋友一起看看吧2025-07-07
C語言循環(huán)語句之重復(fù)執(zhí)行特定的代碼塊
在C語言中分支和循環(huán)語句是實現(xiàn)條件執(zhí)行和重復(fù)執(zhí)行的重要工具,下面這篇文章主要給大家介紹了關(guān)于C語言循環(huán)語句之重復(fù)執(zhí)行特定的代碼塊的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-01-01

