当前位置: 首页 > news >正文

《C++深拷贝与浅拷贝:内存安全的拷贝构造函数实践》

目录

一、默认拷贝构造函数的陷阱(浅拷贝)

二、自定义拷贝构造函数(深拷贝)

三、深拷贝与浅拷贝对比

四、注意事项


一、默认拷贝构造函数的陷阱(浅拷贝)
class MyString {
private:
    char* ptr;  // 指向动态分配的内存
public:
    // 默认拷贝构造函数(按位拷贝)
    MyString(const MyString &st) : ptr(st.ptr) {} // 浅拷贝:仅复制指针地址
};

问题分析:

  • 浅拷贝本质:直接复制指针值,新旧对象共享同一块内存。

  • 致命缺陷

    1. 重复释放:析构时多个对象尝试释放同一内存,导致崩溃。

    2. 悬空指针:一个对象释放内存后,其他对象指针失效。

    3. 数据篡改:通过任意对象修改内容,影响所有共享对象。


二、自定义拷贝构造函数(深拷贝)
class MyString {
private:
    char* ptr;
public:
    // 构造函数:动态分配内存
    MyString(const char* str = nullptr) {
        if (str) {
            int len = strlen(str);
            ptr = new char[len + 1];
            strcpy(ptr, str);
        } else {
            ptr = new char[1];
            *ptr = '\0';
        }
    }

    // 深拷贝构造函数
    MyString(const MyString& st) {
        if (st.ptr) {
            int len = strlen(st.ptr);
            ptr = new char[len + 1];       // 独立分配新内存
            memcpy(ptr, st.ptr, len + 1);  // 复制内容而非指针(比strcpy更高效)
        } else {
            ptr = nullptr;  // 处理空指针边界条件
        }
    }

    // 析构函数:安全释放内存
    ~MyString() {
        delete[] ptr;  // delete[] 匹配 new[]
        ptr = nullptr; // 避免悬空指针
    }
};

关键改进:

  1. 独立内存分配:每个对象持有独立内存块。

  2. 内容复制:使用memcpystrcpy确保数据完整性。

  3. 边界处理:明确处理空指针输入场景。


三、深拷贝与浅拷贝对比
特性浅拷贝深拷贝
内存共享是(多个对象指向同一内存)否(每个对象拥有独立内存)
安全性低(重复释放/悬空指针)高(内存隔离)
适用场景无动态内存管理的简单类型(如int)含指针/动态资源的类(如字符串)
实现复杂度自动生成(无需编码)需显式实现拷贝构造/赋值运算符

四、注意事项
  1. 三人行
    若自定义拷贝构造函数、拷贝赋值运算符或析构函数中的一个,必须显式实现三者。

  2. 优先使用std::string
    避免手动管理内存,直接利用标准库的深拷贝能力。

  3. 深拷贝工具优化

    • 使用memcpy替代strcpy提升大内存块复制效率。

    • 添加nullptr检查防止未定义行为。

http://www.dtcms.com/a/47584.html

相关文章:

  • 【AI认知】大语言生成模型和推理模型的技术差异和应用区别
  • 2025.3.1有关c++类的学习
  • 【树莓派学习】树莓派3B+的安装和环境配置
  • 【数据库初阶】索引(1)
  • Redis Desktop Manager(Redis可视化工具)安装及使用详细教程
  • 随机树算法 自动驾驶汽车的路径规划 静态障碍物(Matlab)
  • ragflow-mysql 启动失败案例分析
  • Linux常见基本指令(一)
  • LeetCode--76. 最小覆盖子串
  • 算法训练(leetcode)二刷第三十八天 | 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和、392. 判断子序列
  • 实验:k8s+keepalived+nginx+iptables
  • 鸿蒙5.0实战案例:基于原生能力获取视频缩略图
  • PyQt——信号与槽
  • 橙心同步助手更新,,支持博客园、头条和语雀
  • 数据结构--队列(C语言实现)
  • 【UCB CS 61B SP24】Lecture 17 - Data Structures 3: B-Trees 学习笔记
  • EMO模型详解及代码复现
  • (保姆级教程)Windows系统本地部署通义万相2.1视频生成模型
  • C++双指针法(尺取法)原理及模板代码与例题
  • 基于springboot的酒店客房管理系统----数据库课程设计
  • 【 <一> 炼丹初探:JavaWeb 的起源与基础】之 JavaWeb的诞生:从 CGI 到 Servlet 的技术演进
  • VulnHub-DarkHole_2靶机搭建保姆级教程2025
  • C++杂记——RAII (Resource Acquisition Is Initialization)
  • 【Java项目】基于SpringBoot的会员制医疗预约服务管理信息系统
  • 算法 BFS搜爆路径问题
  • 深搜专题6:迷宫问题
  • Python爬虫:一文掌握PyQuery模块
  • 【漫话机器学习系列】109.线性无关(Linearly Independent)
  • Rust~String、str、str、String、Box<str> 或 Box<str>
  • 从零开始构建高效Spring Boot应用:实战案例与最佳实践