最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中strcpy()拷貝的3種寫法示例詳解

 更新時(shí)間:2026年05月13日 10:46:01   作者:sanqima  
本文詳細(xì)探討了C++中字符串拷貝函數(shù)strcpy的實(shí)現(xiàn)與優(yōu)化,提供了測試案例和使用場景建議,強(qiáng)調(diào)在性能與安全性之間的權(quán)衡,不同版本適用于不同場景:基礎(chǔ)版適合高性能需求,安全版則優(yōu)先保障穩(wěn)定性,感興趣的朋友跟隨小編一起看看吧

   C++中,有個(gè)常見的字符串拷貝函數(shù):char* strcpy(char* dst, const char* src), 作用是將1個(gè)字符串src,拷貝到另外一個(gè)字符串dst。需要考慮的邊界條件如下:

  • 空指針:dst或src為NULL時(shí)會觸發(fā)非法內(nèi)存訪問。
  • 內(nèi)存重疊:dst和src的地址范圍存在重疊,從前向后拷貝會覆蓋尚未讀取的src內(nèi)容。
  • 空字符串:src僅包含’\0’,需保證拷貝后dst仍然是合法空串。
  • 緩沖區(qū)溢出:dst空間不足導(dǎo)致拷貝越界,是嚴(yán)重的安全漏洞。
  • 結(jié)束符丟失:必須保證拷貝后的dst以’\0’結(jié)尾,否則后續(xù)strlen/printf等字符串操作會越界。

1 基本版本

#include <cassert>
// 對齊標(biāo)準(zhǔn)strcpy簽名,src加const保證常量正確性
char* my_strcpy(char* dst, const char* src) {
    // 調(diào)試期斷言快速定位空指針問題,發(fā)布模式可關(guān)閉斷言不影響性能
    assert(dst != nullptr && src != nullptr);
    // 保存目標(biāo)地址首指針,后續(xù)會移動dst指針
    char* ret = dst;
    // 拷貝邏輯:賦值表達(dá)式返回賦值后的值,遇到'\0'時(shí)循環(huán)終止,自動包含結(jié)束符
    while ((*dst++ = *src++) != '\0');
    return ret;
}

1.1 優(yōu)點(diǎn)

   實(shí)現(xiàn)了核心功能,適合調(diào)用方能保證參數(shù)合法性的高性能場景。

1.2 缺點(diǎn)

  • 若發(fā)布模式關(guān)閉斷言,則傳入空指針,會觸發(fā)未定義行為。
  • 沒有處理內(nèi)存重疊場景,若dst落在src的地址范圍內(nèi)且dst > src,會導(dǎo)致拷貝內(nèi)容錯(cuò)誤。
  • 沒有檢查dst緩沖區(qū)大小,極易出現(xiàn)溢出。

2 進(jìn)階版(支持內(nèi)存重疊)

   參考memmove的語義,處理重疊場景,特別存在地址重疊的情況(如字符串內(nèi)部移動)

#include <cstddef> // size_t定義
char* my_strcpy(char* dst, const char* src) {
    // 發(fā)布期也保留空指針檢查,避免程序崩潰
    if (dst == nullptr || src == nullptr) {
        return nullptr;
    }
    char* ret = dst;
    // 第一步:計(jì)算src總長度(包括末尾'\0')
    size_t len = 0;
    while (src[len] != '\0') len++;
    len += 1; // 包含結(jié)束符的總拷貝字節(jié)數(shù)
    // 第二步:判斷內(nèi)存重疊,選擇拷貝方向
    if (dst < src || dst >= src + len) {
        // 無重疊 / dst在src前面,從前向后拷貝性能更高
        for (size_t i = 0; i < len; i++) {
            dst[i] = src[i];
        }
    } else {
        // 重疊且dst在src后面,從后向前拷貝避免覆蓋未讀取的src內(nèi)容
        // 注意:size_t是無符號類型,禁止寫i>=0(永遠(yuǎn)為真),改為從len倒序到1
        for (size_t i = len; i > 0; i--) {
            dst[i-1] = src[i-1];
        }
    }
    return ret;
}

2.1 特點(diǎn)

  • 即使參數(shù)為空也返回nullptr,避免程序崩潰。
  • 正確處理所有內(nèi)存重疊場景,例如dst = src + 2這類后向重疊場景,也能得到正確結(jié)果。
  • 仍然依賴調(diào)用方保證src以’\0’結(jié)尾、dst緩沖區(qū)足夠大。

3 高級版(緩存區(qū)防護(hù))

   在實(shí)際開發(fā)中,禁止使用無長度限制的strcpy,推薦實(shí)現(xiàn)帶緩沖區(qū)長度的安全版本,徹底避免溢出:

#include <cstddef>
char* my_strcpy_s(char* dst, size_t dst_size, const char* src) {
    if (dst == nullptr || src == nullptr || dst_size == 0) {
        return nullptr;
    }
    size_t i = 0;
    // 最多拷貝dst_size-1個(gè)字符,預(yù)留1個(gè)位置給'\0'
    while (src[i] != '\0' && i < dst_size - 1) {
        dst[i] = src[i];
        i++;
    }
    // 強(qiáng)制加結(jié)束符,保證dst永遠(yuǎn)是合法C字符串(解決strncpy不自動加'\0'的缺陷)
    dst[i] = '\0';
    return dst;
}

3.1 特點(diǎn)

  • 完全避免緩沖區(qū)溢出,即使src遠(yuǎn)長于dst的空間,也只會截?cái)嗟骄彌_區(qū)可容納的最大長度。
  • 始終保證dst以’\0’結(jié)尾,不會出現(xiàn)非法字符串。

4 測試案例

測試場景用例代碼預(yù)期結(jié)果
普通字符串拷貝char dst[20]; my_strcpy(dst, “hello world”);dst內(nèi)容為"hello world"
空字符串拷貝char dst[10]; my_strcpy(dst, “”);dst[0] == ‘\0’
自拷貝char buf[] = “test”; my_strcpy(buf, buf);buf內(nèi)容不變,仍為"test"
后向內(nèi)存重疊char buf[20] = “abcdefgh”; my_strcpy(buf+2, buf);buf內(nèi)容為"ababcdefgh"(基礎(chǔ)版會得到"abababab…"錯(cuò)誤結(jié)果)
空參數(shù)傳入my_strcpy(nullptr, “test”);返回nullptr,程序不崩潰
緩沖區(qū)不足(安全版)char dst[5]; my_strcpy_s(dst, 5, “hello world”);dst內(nèi)容為"hell",自動截?cái)嗖⒓咏Y(jié)束符

5 使用場景

  • const 正確性:src參數(shù)必須加const修飾,既可以傳入const字符串,也能避免函數(shù)內(nèi)部誤修改源字符串。
  • 指針溢出:嵌入式 / 內(nèi)核開發(fā)中,若src地址接近地址空間上限,src + len可能出現(xiàn)指針溢出,可轉(zhuǎn)為uintptr_t整數(shù)類型后再做范圍比較。
  • 性能取舍:如果業(yè)務(wù)不存在重疊場景,基礎(chǔ)版的性能更高;如果優(yōu)先保證安全性,直接使用帶長度的安全版本。

到此這篇關(guān)于C++中strcpy()拷貝的3種寫法示例詳解的文章就介紹到這了,更多相關(guān)C++ strcpy()拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c++實(shí)現(xiàn)reactor高并發(fā)服務(wù)器的詳細(xì)教程

    c++實(shí)現(xiàn)reactor高并發(fā)服務(wù)器的詳細(xì)教程

    這篇文章主要介紹了c++從零實(shí)現(xiàn)reactor高并發(fā)服務(wù)器,包括環(huán)境準(zhǔn)備和基礎(chǔ)知識介紹,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • 詳解VisualS tudio Code開發(fā)Arm嵌入式Linux應(yīng)用

    詳解VisualS tudio Code開發(fā)Arm嵌入式Linux應(yīng)用

    本文介紹如何在 Visual Studio Code 中使用 Yocto Project 生成的 Linux SDK,并針對 Arm 處理器進(jìn)行 C/C++ 應(yīng)用交叉編譯和調(diào)試,感興趣的朋友跟隨小編一起看看吧
    2021-04-04
  • C++中的中介者模式詳解

    C++中的中介者模式詳解

    本文介紹了C++標(biāo)準(zhǔn)庫中的算法,主要包括非修改序列算法(如find、count、for_each等)和修改序列算法(如copy、replace、remove等),以及排序、堆、最小/最大值、數(shù)值和其他算法(如sort、stable_sort、generate等),感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • 舉例講解C語言鏈接器的符號解析機(jī)制

    舉例講解C語言鏈接器的符號解析機(jī)制

    鏈接器的工作主要分為兩個(gè)階段:符號解析和重定位,符號解析的功能是將每個(gè)模塊符號引用綁定到一個(gè)確切的符號定義,這里我們就來舉例講解C語言鏈接器的符號解析機(jī)制
    2016-05-05
  • 一篇文章帶你掌握C++虛函數(shù)的來龍去脈

    一篇文章帶你掌握C++虛函數(shù)的來龍去脈

    虛函數(shù)主要通過V-Table虛函數(shù)表來實(shí)現(xiàn),該表主要包含一個(gè)類的虛函數(shù)的地址表,可解決繼承、覆蓋的問題,下面這篇文章主要給大家介紹了如何通過一篇文章帶你掌握C++虛函數(shù)的來龍去脈,需要的朋友可以參考下
    2022-10-10
  • C++堆和棧的區(qū)別與聯(lián)系講解

    C++堆和棧的區(qū)別與聯(lián)系講解

    今天小編就為大家分享一篇關(guān)于C++堆和棧的區(qū)別與聯(lián)系講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • VS2019配置OpenCV時(shí)找不到Microsoft.Cpp.x64.user的解決方法

    VS2019配置OpenCV時(shí)找不到Microsoft.Cpp.x64.user的解決方法

    這篇文章主要介紹了VS2019配置OpenCV時(shí)找不到Microsoft.Cpp.x64.user的解決方法,需要的朋友可以參考下
    2020-02-02
  • Qt中QStackedWidget的實(shí)現(xiàn)示例

    Qt中QStackedWidget的實(shí)現(xiàn)示例

    QStackedWidget是Qt中的一個(gè)容器控件,它可以包含多個(gè)子控件,類似于一疊卡片,下面就來詳細(xì)的介紹一下Qt中QStackedWidget的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2026-03-03
  • 圖的鄰接表存儲表示示例講解

    圖的鄰接表存儲表示示例講解

    這篇文章主要介紹了圖的鄰接表存儲表示,大家參考使用
    2013-11-11
  • C++中的函數(shù)返回值與拷貝用法

    C++中的函數(shù)返回值與拷貝用法

    這篇文章主要介紹了C++中的函數(shù)返回值與拷貝用法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11

最新評論

南汇区| 攀枝花市| 临桂县| 余庆县| 普陀区| 吴桥县| 溆浦县| 大宁县| 荆门市| 盖州市| 昭觉县| 葵青区| 阿勒泰市| 淳安县| 荆门市| 大石桥市| 来安县| 连南| 巨鹿县| 湘潭县| 元江| 务川| 双流县| 黑龙江省| 孟村| 山阳县| 建水县| 河池市| 延吉市| 宁蒗| 东台市| 林周县| 当涂县| 高雄市| 金塔县| 丰镇市| 深圳市| 江北区| 广东省| 南江县| 陆良县|