当前位置:

首页 > 编程开发 > C++中strcpy()拷贝的3种写法示例详解

C++中strcpy()拷贝的3种写法示例详解

C++中strcpy的三种实现:基本版仅处理正常拷贝,不检查空指针、内存重叠及缓冲区溢出;进阶版通过判断地址范围选择拷贝方向,支持内存重叠并返回空指针;高级版限制拷贝长度并强制添加结束符,彻底杜绝溢出风险。

本文目录

    聊到 C++ 里的字符串拷贝,大家第一反应肯定是 strcpy。这个函数看起来简单,但真要自己实现一遍,会发现边界条件远比你想象的多。先来列几个必须处理的“暗礁”:

    C++中strcpy()拷贝的3种写法示例详解

    • 空指针:dst 或 src 为 NULL,直接非法访问内存,程序说崩就崩。
    • 内存重叠:dst 和 src 的地址范围有交叉,从前向后拷贝时会覆盖还没读完的 src 内容——结果自然就错了。
    • 空字符串:src 只有一个 '\0',拷贝后 dst 也必须是合法的空串,不能多出垃圾字符。
    • 缓冲区溢出:dst 空间不够,拷贝越界——这是最典型的安全漏洞,黑客最爱拿它做文章。
    • 结束符丢失:拷贝完必须保证 dst 以 '\0' 结尾,否则后面 strlen、printf 这些函数会一路读到天荒地老。

    1 基本版本

    #include 
    // 对齐标准strcpy签名,src加const保证常量正确性
    char* my_strcpy(char* dst, const char* src) {
        // 调试期断言快速定位空指针问题,发布模式可关闭断言不影响性能
        assert(dst != nullptr && src != nullptr);
        // 保存目标地址首指针,后续会移动dst指针
        char* ret = dst;
        // 拷贝逻辑:赋值表达式返回赋值后的值,遇到'\0'时循环终止,自动包含结束符
        while ((*dst++ = *src++) != '\0');
        return ret;
    }

    1.1 优点

    核心功能完整,代码极其简洁。如果调用方能保证参数绝对合法,这个版本的性能是最高的。

    1.2 缺点

    • 发布模式下一旦关闭断言,传入空指针就会触发未定义行为,程序可能在莫名其妙的地方崩掉。
    • 完全不处理内存重叠——如果 dst 落在 src 的范围内且 dst > src,拷贝结果会乱掉。
    • 对 dst 缓冲区大小没有做任何检查,溢出几乎是必然的(只要源串够长)。

    2 进阶版(支持内存重叠)

    这个版本参考了 memmove 的思路,专门处理地址重叠的场景,比如字符串内部移动。

    #include  // size_t定义
    char* my_strcpy(char* dst, const char* src) {
        // 发布期也保留空指针检查,避免程序崩溃
        if (dst == nullptr || src == nullptr) {
            return nullptr;
        }
        char* ret = dst;
        // 第一步:计算src总长度(包括末尾'\0')
        size_t len = 0;
        while (src[len] != '\0') len++;
        len += 1; // 包含结束符的总拷贝字节数
        // 第二步:判断内存重叠,选择拷贝方向
        if (dst < src || dst >= src + len) {
            // 无重叠 / dst在src前面,从前向后拷贝性能更高
            for (size_t i = 0; i < len; i++) {
                dst[i] = src[i];
            }
        } else {
            // 重叠且dst在src后面,从后向前拷贝避免覆盖未读取的src内容
            // 注意:size_t是无符号类型,禁止写i>=0(永远为真),改为从len倒序到1
            for (size_t i = len; i > 0; i--) {
                dst[i-1] = src[i-1];
            }
        }
        return ret;
    }

    2.1 特点

    • 即使参数传了空指针,也直接返回 nullptr,不会让程序崩溃。
    • 所有内存重叠情况都能正确处理,比如 dst = src + 2 这种后向重叠,结果完全正确。
    • 不过依然依赖调用方保证 src 以 '\0' 结尾,以及 dst 缓冲区足够大。

    3 高级版(缓冲区防护)

    实际项目中,绝对不要用无长度限制的 strcpy。下面这个版本带缓冲区长度参数,彻底杜绝溢出风险。

    #include 
    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个字符,预留1个位置给'\0'
        while (src[i] != '\0' && i < dst_size - 1) {
            dst[i] = src[i];
            i++;
        }
        // 强制加结束符,保证dst永远是合法C字符串(解决strncpy不自动加'\0'的缺陷)
        dst[i] = '\0';
        return dst;
    }

    3.1 特点

    • 完全避免缓冲区溢出——就算 src 比 dst 空间长得多,也只会截断到缓冲区能容纳的最大长度。
    • 永远强制在末尾加 '\0',不会出现非法字符串(很多人在用 strncpy 时容易忽略这个细节)。

    4 测试案例

    测试场景用例代码预期结果
    普通字符串拷贝char dst[20]; my_strcpy(dst, “hello world”);dst内容为"hello world"
    空字符串拷贝char dst[10]; my_strcpy(dst, “”);dst[0] == ‘\0’
    自拷贝char buf[] = “test”; my_strcpy(buf, buf);buf内容不变,仍为"test"
    后向内存重叠char buf[20] = “abcdefgh”; my_strcpy(buf+2, buf);buf内容为"ababcdefgh"(基础版会得到"abababab…"错误结果)
    空参数传入my_strcpy(nullptr, “test”);返回nullptr,程序不崩溃
    缓冲区不足(安全版)char dst[5]; my_strcpy_s(dst, 5, “hello world”);dst内容为"hell",自动截断并加结束符

    5 使用场景

    • const 正确性:src 参数必须加 const,这样既能接收 const 字符串,也能防止函数内部误修改源数据。
    • 指针溢出:嵌入式或内核开发中,如果 src 地址接近地址空间上限,src + len 可能发生指针溢出。可以先把地址转成 uintptr_t 再做范围比较,更安全。
    • 性能取舍:如果在你的业务场景中根本不会出现内存重叠,用基础版就好,while 循环一次到位,性能最优。如果安全是第一优先级,别犹豫,直接上带长度的安全版本。
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    Amazon Bedrock权限指南:MCP检索怎样绑定真实用户并阻止绕过
    Amazon Bedrock权限指南:MCP检索怎样绑定真实用户并阻止绕过

    AWS发布Managed Knowledge Base经AgentCore Gateway暴露为MCP工具的分层权限方案:由可信拦截器注入用户身份,独立策略复核,再限制知识库直连。ACL感知检索按收到的身份过滤结果,本身不能替代身份认证与授权。

    Amazon Bedrock迁移指南更新:用amazon-bedrock Skill规划托管知识库切换
    Amazon Bedrock迁移指南更新:用amazon-bedrock Skill规划托管知识库切换

    AWS为Agent Toolkit for AWS的amazon-bedrock Skill加入知识库迁移指南,支持先只读分析,再规划并行创建或生成IaC模板。切换到Managed Knowledge Base还需更新Retrieve请求结构、同步数据并验证权限与检索结果,不能把创建资源等同于迁移完成。

    llama.cpp SYCL进展:b12319预发布构建上线,b12320源码修复大缓冲AOT问题
    llama.cpp SYCL进展:b12319预发布构建上线,b12320源码修复大缓冲AOT问题

    llama.cpp b12319已从源码标签推进到带下载资产的预发布构建;b12320源码标签关联提交修复SYCL AOT超过4GB时的异常输出,并调整构建选项。需区分安装资产与源码阶段,不能将所有GPU后端或所有大模型都列为受影响范围。

    Ducter 0.0.43:设备卡片指向可操作的Mac,修正无屏服务器提示
    Ducter 0.0.43:设备卡片指向可操作的Mac,修正无屏服务器提示

    Ducter 0.0.43修正服务器home与执行Mac之间的设备卡片显示:用手机、用电脑会标出实际Mac并跳转到其卡片,无屏Linux服务器不再提示该功能“以后会有”。这是设备发现与状态呈现修复,不是Linux新增桌面控制能力。

    Browser Use 1.0.3:修复MCP断管退出,改进无界面浏览器与超时诊断
    Browser Use 1.0.3:修复MCP断管退出,改进无界面浏览器与超时诊断

    Browser Use 1.0.3修复--cli-mcp在客户端提前断开管道后的异常退出,改进无显示环境下的Chromium启动、无效CDP地址诊断与取消云任务后的下载收尾。升级时还应检查所有被忽略的0.x ActionResult字段警告。

    llama.cpp 后端更新:Adreno 分解注意力、CUDA 空分块修复与 SYCL 缓存
    llama.cpp 后端更新:Adreno 分解注意力、CUDA 空分块修复与 SYCL 缓存

    llama.cpp b12314为Adreno OpenCL加入分解Flash Attention,b12316修复CUDA MoE空分块路径读取,b12319源码标签改用SYCL线程本地设备ID缓存。三个后端、两种发布阶段需分别核对,不能合并成统一性能提升或全平台安全结论。

    LangChain JS 适配包更新:MCP与OpenAI提高Zod下限,连接器同步依赖
    LangChain JS 适配包更新:MCP与OpenAI提高Zod下限,连接器同步依赖

    LangChain JS的MCP、IBM、OpenAI及Tavily适配包要求安装Zod 4.6.6及以上,OpenRouter、Together AI、xAI和Neo4j同步相关依赖。本文区分直接安全约束与传递依赖更新,给出锁文件和schema兼容性核对方法。

    LangChain Core 1.8.0:最低 Python 升至3.11,加入决策模型能力
    LangChain Core 1.8.0:最低 Python 升至3.11,加入决策模型能力

    langchain-core 1.8.0结束Python 3.10支持,最低要求变为Python 3.11,并加入decision models。Python 3.10仍会解析到1.7.x;升级前应同时核对解释器、锁文件、CI镜像与部署运行时,不把TypeSafe包的迁移要求混同于全部LangChain包。

    GitHub Copilot CLI 1.0.110-2:压缩遵守会话额度,修复插件设置覆盖
    GitHub Copilot CLI 1.0.110-2:压缩遵守会话额度,修复插件设置覆盖

    GitHub Copilot CLI 1.0.110-2预发布补丁让/compact遵守会话AI credit限制,改进失败回复标记,并修复无效配置时插件操作覆盖其他设置的问题。会话清理会跳过其他进程正在使用的会话,适合核对多终端与插件工作流。

    Ducter 0.0.42:消息定向回复上线,串联密钥卡片与 Mac 手机操作
    Ducter 0.0.42:消息定向回复上线,串联密钥卡片与 Mac 手机操作

    Ducter 0.0.42加入对单条消息及选中文字回复;本轮0.0.39—0.0.41还调整主动提醒、密钥请求卡片及Mac上的手机和应用操作。更新涉及本地权限与远端执行边界,应按版本逐项确认,而非默认所有设备都能使用全部功能。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。