C++ 浅拷贝(Shallow Copy)与深拷贝(Deep Copy)全面解析:指针成员、内存管理与面试要点
教程知识库【免费下载链接】tech-interview-for-developer 신입 개발자 전공 지식 기술 면접 백과사전 项目地址https://gitcode.com/GitHub_Trending/te/tech-interview-for-developer点击查看免费下载本文是 tech-interview-for-developer 仓库中《[Cpp] 얕은 복사 vs 깊은 복사》一文的深度展开版。文章以拷贝对象时指针成员到底该共享还是该复制这一核心问题为主线先完整保留原文档中 shallow copy 与 deep copy 的定义及代码示例再结合仓库内《[C] 포인터(Pointer)](Language/[C] 포인터(Pointer).md) 与《[C] 동적할당](Language/[C] 동적할당.md) 的指针、malloc/free 知识补全可编译运行的完整示例并延伸到 C 默认拷贝构造函数、赋值运算符、Rule of Three 等面试高频考点。读完你不仅能准确回答浅拷贝与深拷贝的区别还能在纸上写出安全的自定义拷贝构造函数与赋值运算符并说清楚 double free、悬空指针、内存泄漏三种经典事故的成因。一、为什么要区分浅拷贝与深拷贝C 中拷贝指的是将一个对象的全部成员变量复制到另一个对象。当类的成员都是int、double这类值类型时拷贝就是简单的逐成员赋值不存在任何歧义。问题出现在成员变量是指针的时候——指针里存的是地址那么拷贝时只复制地址本身两个指针指向同一块内存还是连同地址指向的那块内存里的数据一起复制每个对象各自拥有一块独立内存这两个选择分别对应浅拷贝shallow copy与深拷贝deep copy。本文用原文档中最经典的struct Test { char *ptr; }结构来逐步拆解。二、浅拷贝Shallow Copy只复制成员变量的值1. 定义浅拷贝将一个对象的所有成员变量的值复制到另一个对象。这里的值对指针成员而言就是地址值。结果就是src与dest两个对象的ptr成员保存着同一个地址它们指向同一块内存。2. 原文档的代码示例原文档给出的shallow_copy如下struct Test { char *ptr; }; void shallow_copy(Test src, Test dest) { dest.ptr src.ptr; // 仅拷贝指针本身地址值不复制指向的数据 }这段代码的核心只有一行dest.ptr src.ptr;。它完成了指针地址的赋值但没有为dest.ptr分配任何新内存也没有把src.ptr指向的字符串内容拷贝过去。3. 内存视角两个指针、一块内存src.ptr ──┐ ├──► [ h | e | l | l | o | \0 ] dest.ptr ─┘即两个指针变量指向同一块堆内存。从仓库内《[C] 포인터(Pointer)](Language/[C] 포인터(Pointer).md) 的角度看dest.ptr与src.ptr持有的是同一个주소값地址值对其中任何一个指针做*ptr解引用读到的都是同一份数据。4. 浅拷贝的风险对象创建与删除阶段的运行期错误原文档明确指出shallow_copy使用后与对象创建생성和删除삭제相关的很多编程错误会在程序运行期间暴露出来。具体来说至少有三类经典事故1双重释放double free若两个对象的ptr指向同一块malloc出来的内存那么两个对象分别析构时各自调用一次free(ptr)同一块内存被释放两次属于未定义行为UB通常表现为运行时崩溃或堆损坏。2悬空指针dangling pointer若其中一个对象先被销毁并free了这块内存另一个对象的ptr仍保留着这个已释放的地址后续再访问就变成访问已释放内存use-after-free。3意外共享数据aliasing因为共享同一块数据修改src.ptr[0]会隔空改变dest看到的内容——这不是通常意义上的拷贝语义。因此原文档给出了一条重要结论浅拷贝意味着程序员必须完全清楚自己在做什么只有在这样的前提下才能小心使用。5. 浅拷贝的适用场景大多数情况下浅拷贝用于不复制实际数据而仅仅传递关于某个复杂数据结构的信息如指针、引用、句柄的场合。典型的例子包括传递只读视图/借用语义多个观察者共享同一份底层数据谁都不拥有它图的邻接表、共享缓存、引用计数对象如std::shared_ptr的拷贝本质是对控制块的浅拷贝函数参数传递指针/引用避免大对象整体复制的开销。需要注意的是对浅拷贝产生的对象执行删除delete/free时必须格外小心因为释放操作会波及所有共享这块内存的对象。这也是原文档特别强调얕은 복사로 만들어진 객체를 삭제할 때는 조심해야 한다删除浅拷贝对象时要小心的原因。三、深拷贝Deep Copy指针指向的对象也一并复制1. 定义深拷贝不仅复制所有成员变量的值对指针变量所指向的每一个对象也全部进行复制。深拷贝的语义是完全独立的副本拷贝完成后两个对象各自拥有一块内容相同、但互不相干的内存。2. 原文档的代码示例struct Test { char *ptr; }; void deep_copy(Test src, Test dest) { dest.ptr (char*)malloc(strlen(src.ptr) 1); // 先为目标分配一块新内存 strcpy(dest.ptr, src.ptr); // 再把源数据内容复制过去 }这段代码分两步完成真正的复制malloc(strlen(src.ptr) 1)按源字符串长度1留给结尾的\0为dest.ptr分配一块新的堆内存strcpy(dest.ptr, src.ptr)把源字符串的内容逐字节复制到新内存中。关于malloc的语义可参考仓库内《[C] 동적할당](Language/[C] 동적할당.md)void* malloc(size_t size)在堆Heap区域分配size字节的内存返回void*指针使用时需要类型转换C 中应使用static_castchar*或直接new char[]分配失败时返回NULL因此生产代码中应检查返回值。同时该文强调할당한 메모리는 반드시 해제하자分配的内存必须释放否则造成 메모리 릭内存泄漏——这一点在深拷贝中同样成立每次深拷贝分配的新内存都必须在对应对象析构时free。3. 内存视角两个指针、两块内容相同的内存src.ptr ──► [ h | e | l | l | o | \0 ] dest.ptr ──► [ h | e | l | l | o | \0 ]两块内存地址不同、内容相同修改任意一个都不会影响另一个。4. 深拷贝版本的完整可运行代码为了让原文档示例真正可复制、可运行下面补充必要的头文件、free释放逻辑与验证输出注意原文档中缺少这些部分#include cstdio // printf #include cstdlib // malloc / free #include cstring // strlen / strcpy #include cassert // assert struct Test { char *ptr; }; void shallow_copy(Test src, Test dest) { dest.ptr src.ptr; // 浅拷贝共享同一块内存 } void deep_copy(Test src, Test dest) { dest.ptr (char*)malloc(strlen(src.ptr) 1); // 分配新内存 if (dest.ptr nullptr) return; // 分配失败保护 strcpy(dest.ptr, src.ptr); // 深拷贝复制内容 } int main() { Test a; a.ptr (char*)malloc(6); strcpy(a.ptr, hello); Test b, c; shallow_copy(a, b); // b.ptr 与 a.ptr 指向同一块内存 deep_copy(a, c); // c.ptr 拥有独立内存 b.ptr[0] H; // 修改 b 会影响 a共享内存 printf(a.ptr %s\n, a.ptr); // 输出 Hello —— 被 b 影响 printf(c.ptr %s\n, c.ptr); // 输出 hello —— 深拷贝不受影响 free(a.ptr); // a 释放 // free(b.ptr); // 错误b.ptr 与 a.ptr 相同再次 free 就是 double free free(c.ptr); // c 的独立内存正常释放 return 0; }运行结果可以直观验证两种拷贝的差异修改b.ptr[0]后a的内容跟着改变浅拷贝共享而c的内容保持不变深拷贝独立。四、浅拷贝 vs 深拷贝对比一览维度浅拷贝Shallow Copy深拷贝Deep Copy指针成员的处理只复制地址值地址值 指向的数据一并复制拷贝后指针关系指向同一块内存共享各自指向独立内存互不影响内存开销低无需新分配高需按数据大小分配新内存修改隔离性修改一方会影响另一方完全隔离析构风险double free / 悬空指针 / 泄漏只要正确配对 free 即安全典型用途传递复杂数据结构的信息、借用/共享语义需要真正独立副本的绝大多数场景五、深挖底层C 默认的拷贝构造函数与赋值运算符原文档用函数形式演示了两种拷贝但在真实 C 类中拷贝的入口通常是编译器自动生成的拷贝构造函数copy constructor与拷贝赋值运算符copy assignment operator。它们的行为就是逐成员拷贝memberwise copy即对指针成员做浅拷贝。class String { public: char *ptr; String(const char *s) { ptr (char*)malloc(strlen(s) 1); strcpy(ptr, s); } // 编译器自动生成的默认拷贝构造函数 ≈ 浅拷贝 // String(const String other) : ptr(other.ptr) {} // 默认拷贝赋值运算符 ≈ 浅拷贝 // String operator(const String other) { ptr other.ptr; return *this; } ~String() { free(ptr); } // 析构释放内存 }; int main() { String s1(hello); String s2 s1; // 调用默认拷贝构造 → s2.ptr 与 s1.ptr 相同 // s1、s2 析构时都会 free 同一块内存 → double free }上述代码几乎必然在程序退出时崩溃两个对象共享一块内存析构时各自free一次。这正是原文档所说객체 생성과 삭제에 관련된 많은 프로그래밍 오류가 프로그램 실행 시간에 발생的根源——错误不是编译期报错而是运行期才暴露。解决之道自定义拷贝三件套Rule of Three只要类持有堆内存资源指针就必须同时提供自定义拷贝构造函数深拷贝自定义拷贝赋值运算符深拷贝并注意处理自赋值与旧资源释放析构函数释放自己的资源。class String { char *ptr; public: String(const char *s) { ptr (char*)malloc(strlen(s) 1); strcpy(ptr, s); } // 拷贝构造深拷贝 String(const String other) { ptr (char*)malloc(strlen(other.ptr) 1); strcpy(ptr, other.ptr); } // 拷贝赋值深拷贝 自赋值保护 释放旧资源 String operator(const String other) { if (this ! other) { // 自赋值保护 free(ptr); // 释放旧内存 ptr (char*)malloc(strlen(other.ptr) 1); strcpy(ptr, other.ptr); } return *this; } ~String() { free(ptr); } // 释放自己的内存 };深拷贝还会出现在值传递、按值返回等场景中函数参数按值传递时、函数按值返回对象时都会触发拷贝构造。对于大对象这会产生额外分配开销这也是现代 C 引入移动语义move semantics、std::move、以及 Vector Container 等容器内部按需扩容capacity与size分离的动机之一——不过移动语义属于进阶话题面试时通常先答清楚浅拷贝与深拷贝本身。六、原文档的实践结论为什么说浅拷贝在实战中很少用原文档最后给出了非常务实的结论这里原样保留并补充阐释실제로 얕은 복사는 실무에서 거의 사용되지 않는다. 대부분 깊은 복사를 사용해야 하는데, 복사되는 자료구조의 크기가 작으면 더욱 깊은 복사가 필요하다.实际上浅拷贝在实战中几乎不被使用。大多数情况应该使用深拷贝被拷贝的数据结构越小就越应当使用深拷贝。解读两点默认选择深拷贝只要类的语义是值语义value semantics——拷贝后各对象相互独立——就必须深拷贝。这也是 C 标准库的默认立场std::string、std::vector的拷贝都是深拷贝。数据结构越小越该深拷贝数据量小意味着深拷贝的额外分配成本可以忽略此时用浅拷贝省下的那点开销远不及它带来的 double free、悬空指针风险大。反过来当数据量巨大且需要频繁拷贝时正确的做法也不是退回到浅拷贝而是改用引用/指针传递、共享所有权如智能指针等显式语义。七、面试高频追问与总结把本文内容压缩成一套面试应答框架一句话定义浅拷贝只复制成员变量的值指针成员只复制地址深拷贝连指针指向的对象也一起复制。危险在哪里浅拷贝下多个对象共享同一块内存析构时重复释放double free、释放后继续访问悬空指针、修改互相影响aliasing。编译器默认行为C 默认拷贝构造/赋值运算符是逐成员浅拷贝持有裸指针的类必须自定义Rule of Three。什么时候用浅拷贝传递复杂数据结构的信息而不复制实际数据、借用/共享语义如引用计数共享此时必须明确所有权谁负责释放。删除时的注意浅拷贝产生的对象删除时要格外小心避免二次释放波及共享内存的其它对象。实战倾向绝大多数场景用深拷贝数据结构越小越应深拷贝以极低的成本换取完全隔离的安全语义。八、延伸阅读仓库内相关资料[Language/[C] 포인터(Pointer).md](Language/[C] 포인터(Pointer).md)指针的本质、地址与解引用是理解浅/深拷贝的前提。[Language/[C] 동적할당.md](Language/[C] 동적할당.md)malloc / calloc / realloc / free 的完整说明深拷贝中每块新内存的生命周期管理。[Language/[C] Vector Container.md](Language/[C] Vector Container.md)标准库容器vector的拷贝vectorType v2(v);即深拷贝的典型应用。[Language/[C] 가상 함수(virtual function).md](Language/[C] 가상 함수(virtual function).md)当类包含虚函数时深拷贝还要考虑多态克隆clone问题可作为进阶话题。本文对应的原始笔记位于 Language/[Cpp] shallow copy vs deep copy.md其参考文献为《코딩 인터뷰 완전분석Cracking the Coding Interview》读者可将本文与原文对照阅读。赞分享教程知识库【免费下载链接】tech-interview-for-developer 신입 개발자 전공 지식 기술 면접 백과사전 项目地址https://gitcode.com/GitHub_Trending/te/tech-interview-for-developer点击查看免费下载相关推荐StarWars EF Core数据访问详解StarWarsContext关系建模与数据库自动种子数据StarWars EF Core数据访问详解StarWarsContext关系建模与数据库自动种子数据 StarWars 是一个基于 GraphQL forCPython copy 模块深入解析浅拷贝、深拷贝与 replace 协议的完整指南CPython copy 模块深入解析浅拷贝、深拷贝与 replace 协议的完整指南 导读 copy 模块是 Python 标准库中负责浅拷贝与深拷贝编程语言语言运行时解释器标准库CANN asc-devkit SIMD-API C-API asc_int82int32函数asc_int82int32 废弃 产品支持情况 | 产品 | 是否支持 | | | : : | | Ascend 950PR/Ascend 950DT | √人工智能深度学习算子库CANNAscend上一篇B站缓存视频格式转换技术指南从问题诊断到高效解决方案下一篇如何快速提取MSI文件lessmsi完整使用指南与Windows安装包解析技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

3DCellForge 图生3D 实战指南:把任意参考图变成可交互 GLB 3D 模型

3DCellForge 图生3D 实战指南:把任意参考图变成可交互 GLB 3D 模型

3DCellForge 图生3D 实战指南:把任意参考图变成可交互 GLB 3D 模型 【免费下载链接】3DCellForge AI-powered interactive 3D model generation, inspection, and presentation studio. 项目地址: https://gitcode.com/gh_mirrors/3d/3DCellForge 3DCellForg…

2026/10/3 16:00:05 阅读更多 →
文科生自学转码拿下大厂前端 Offer:一份可复制的校招实战复盘

文科生自学转码拿下大厂前端 Offer:一份可复制的校招实战复盘

文档教程知识库 【免费下载链接】CS-Base 图解计算机网络、操作系统、计算机组成、数据库,共 1000 张图 50 万字,破除晦涩难懂的计算机基础知识,让天下没有难懂的八股文!🚀 在线阅读:https://xiaolincodin…

2026/10/2 15:42:42 阅读更多 →
给产品接入MCP Server:让AI Agent自动发现并调用你的服务

给产品接入MCP Server:让AI Agent自动发现并调用你的服务

前阵子给我的小产品补了个很不起眼但影响很深远的接口:一个 MCP server。做完以后,效果很有意思——原本只能通过网页表单和 REST API 被人调用的报价服务,现在能被各种 AI agent 自动发现、自动调用、自动把报价单带回来。放在 2026 年这个节…

2026/10/3 15:46:32 阅读更多 →

最新新闻

AI重塑财务的真正难题_德勤未来财务报告深度解读_CSDN

AI重塑财务的真正难题_德勤未来财务报告深度解读_CSDN

AI 重塑财务的真正难题:从“算得更快”到“决定得更好”——读德勤《AI 助力下的财务未来》 摘要:德勤在《AI 助力下的财务未来》中描绘了 2030 年的企业财务:交易处理高度自动化,智能体参与分析和执行,财务部门从事后…

2026/10/3 17:49:27 阅读更多 →
淮安醋酸盐系列专业厂家2026年发展现状与市场占有率及排名研究分析报告

淮安醋酸盐系列专业厂家2026年发展现状与市场占有率及排名研究分析报告

醋酸盐系列哪家厂家更专业?2026年醋酸盐市场格局如何?采购醋酸盐产品时应该重点关注哪些指标?这三个问题,是当前食品、饲料、化工、医药等领域采购人员搜索频率最高的问题。随着下游行业对原料品质要求不断提升,醋酸盐供应市场正在加速分化&#xff0…

2026/10/3 17:48:26 阅读更多 →
常州管家婆系统制造厂商哪家更值得选 口碑服务商盘点

常州管家婆系统制造厂商哪家更值得选 口碑服务商盘点

常州管家婆系统制造厂商哪家更值得选?这是很多本地中小企业主在选管理软件时最常问的一句话。今天就围绕大家关心的几个高频问题,做一次口碑服务商的盘点解读,帮你在选型路上少走弯路。Q1:管家婆系统到底能帮企业解决哪些问题?很多中小微企…

2026/10/3 17:48:26 阅读更多 →
8轴电机控制板程序

8轴电机控制板程序

每个轴使用的定时器通道 以及硬件引脚定义如下:1轴:PUL:TIM8 CH2;DIR:PF14;EN:PF15;2轴:PUL:TIM8 CH3;DIR:PFF12;EN&#…

2026/10/3 17:46:25 阅读更多 →
DeepSeek    LeetCode 213. 打家劫舍 II Java实现

DeepSeek LeetCode 213. 打家劫舍 II Java实现

LeetCode 213. 打家劫舍 II - Java 实现 题目分析 与打家劫舍 I 的区别:房屋首尾相连成环,第一个和最后一个不能同时偷。 核心思路:把环形问题拆成两个线性问题: 偷 [0, n-2] 范围内的房子(不偷最后一间)偷…

2026/10/3 17:45:24 阅读更多 →
LangGraph 从入门到实战(02):节点、边、状态——组装你的第一个多步图

LangGraph 从入门到实战(02):节点、边、状态——组装你的第一个多步图

LangGraph 从入门到实战(02):节点、边、状态——组装第一个多步图 第 01 篇跑通了最简的一步图。这一篇把它升级成「多节点、有条件分支、自定义合并」的真正雏形——这三件事正是 Agent 循环的三块基石。 一、多节点:一条「流水线」 把一个数字先 +1 再翻倍,用两个节点…

2026/10/3 17:45:24 阅读更多 →

日新闻

把回忆蒸馏成 AI 的浪漫实验:为什么你需要前任.skill 完整指南

把回忆蒸馏成 AI 的浪漫实验:为什么你需要前任.skill 完整指南

把回忆蒸馏成 AI 的浪漫实验:为什么你需要前任.skill 完整指南 【免费下载链接】ex-skill 前任 skill 项目地址: https://gitcode.com/gh_mirrors/exsk/ex-skill 前任.skill 是一个运行在 Claude Code 上的开源 Skill:导入微信、iMessage、短信、…

2026/10/3 0:00:27 阅读更多 →
45个经典Linux面试题:从命令到网络排障的完整考点解析

45个经典Linux面试题:从命令到网络排障的完整考点解析

刚开始带应届生的时候,我最头疼的就是他们拿着一摞Linux面试题背得滚瓜烂熟,一上机全露馅。后来自己从被面的人变成面别人的人,才慢慢摸清楚:Linux面试题考的根本不是答案本身,而是你面对一个不确定的系统问题时&#…

2026/10/3 0:01:28 阅读更多 →
SAP生产预留实战指南:MB21/MB23/MB25协同与MRP集成

SAP生产预留实战指南:MB21/MB23/MB25协同与MRP集成

简介:本资源是一份面向SAP ABAP开发人员、生产计划专员及ERP实施顾问的实操型操作指南,聚焦SAP生产预留核心业务场景,系统解决物料预留创建、查询、校验与批量处理等高频问题。文档以结构化方式覆盖预留背景原理、OMC2编码规则、工厂级参数配…

2026/10/3 0:01:28 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/3 9:14:33 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/3 9:47:50 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/3 9:42:31 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →