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

「C++之STL」关于在模拟实现STL容器中的深浅拷贝问题

文章目录

  • 前言
    • 杨辉三角
    • 深浅拷贝问题
    • 模拟实现的vector对题目杨辉三角引发的程序崩溃
    • 原因
    • 解决办法

前言

在学习STL容器中,不仅需要学会容器的使用,同时也需要了解容器的大体框架以及各个函数的模拟实现才能更好的去了解这个容器;

杨辉三角

在LeetCode中有一道这样的题目,给定一个非负整数 numRow ,生成「杨辉三角」的前 numRows 行;
[题目链接]
在这里插入图片描述
从图中可知杨辉三角的概念,即每一个数都是它上方左右两数的和,且整个三角形呈对称关系;
这题若是使用c语言的话可以直接用二维数组的思路进行作答;

//c
int** generate(int numRows, int* returnSize, int** returnColumnSizes){int** ret = malloc(sizeof(int*)*numRows); //申请返回的指针空间*returnSize = numRows; //返回行数*returnColumnSizes = malloc(sizeof(int*)*numRows); //为每一列分配空间for(int i=0;i<numRows;i++){ret[i] = malloc(sizeof(int)*(i+1));//分配每一行的个数(*returnColumnSizes)[i] = i + 1;//为第一个以及最后一个赋值ret[i][0] = 1;ret[i][i] = 1;for(int j=1;j<i;j++){ret[i][j] = ret[i-1][j-1] + ret[i-1][j];}}return ret;
}

若是使用C++的话则可以使用STL容器中的vector来模仿二维数组;

//c++
class Solution {
public:vector<vector<int>> generate(int numRows) {vector<vector<int>>triangle(numRows);for(int i = 0;i<numRows;i++){triangle[i].resize(i+1,0);triangle[i].front() = triangle[i].back() = 1;}for(int i = 0;i<numRows;i++){for(int j = 0;j<triangle[i].size();j++){if(triangle[i][j]!=1){triangle[i][j] = triangle[i-1][j-1]+triangle[i-1][j];}}}return triangle;}
};

且其思路与C语言中的二维数组法相同;

深浅拷贝问题

[【C++】STL之String模拟实现 ]
在该篇文章中,我写出了对于类似拷贝构造或者扩容时应该进行的深浅拷贝;
在学过一段时间的C++后就能知道,在默认成员函数中存在拷贝构造函数以及赋值重载等函数;
这些默认成员函数在没有显式定义时,编译器会自动生成一个默认的对应函数;
而对于编译器自动生成的拷贝构造以及赋值重载函数,对于内置类型将会进行值拷贝,而对于自定义类型来说将会调用它的默认构造函数;
在这篇文章中对于类似扩容,拷贝构造以及赋值重载函数,采用的方法都是:

开辟一块新的空间,再将原先的数据使用memcpy函数或者在string中使用的strcpy函数拷贝到新的空间;

拷贝构造
//拷贝
My_string::string::string(const string& str):_str(new char[str._size+1]),_size(str._size),_capacity(str._size)
{memcpy(_str, str._str,str._size);_str[_size] = '\0';
}
扩容
 //扩容void My_string::string::reserve(size_t n){if (n > _capacity) {char* temp = new char[n+1];//多开1的空间确保n为有效数据的空间而+1为给'\0'的无效空间strcpy(temp, _str);_capacity = n;delete[]_str;_str = temp;}}
赋值重载
My_string::string& My_string::string::operator=(const string& str)//赋值操作符重载{if (this != &str) {char* temp = new char[str._capacity+1];strcpy(temp, str._str);delete[]_str;_str = temp;_size = str._size;_capacity = str._capacity;}return *this;}

模拟实现的vector对题目杨辉三角引发的程序崩溃

同时,我模拟实现了一个vector容器,这个容器的完成程度暂且不提,在这里的拷贝构造函数,扩容以及赋值重载依旧按照模拟实现string那样使用memcpy进行原数据拷贝到新空间的方法;

//拷贝构造vector(const vector<T>&v){T* tmp = new T[v.size()];_start = tmp;memcpy(tmp,v._start,sizeof(T)*v.size());_finish = _end_of_storage = _start + v.size();}/*扩容reserve*/void reserve(size_t n){if(n>capacity()){size_t count = size();T* tmp = new T[n];memcpy(tmp,_start,sizeof(T)*count);delete[]_start;_start = tmp;_finish = _start+count;_end_of_storage = _start+n;}}

而使用这种方法对杨辉三角题目进行测试时,程序将崩溃;

在这里插入图片描述

而程序崩溃的原因为析构函数;
在这里插入图片描述

原因

当程序在析构函数处崩溃且析构函数并没有其他问题的时候,应该及时将问题的思路转变到对象的深浅拷贝问题;
而这里出的错误正是使用memcpy函数进行拷贝从而造成的浅拷贝;
那为什么在这里使用memcpy时将会造成浅拷贝;
在模拟这些成员函数中,一般优先会想到的类型为内置类型,即语言标准指定,编译器自带的类型;
如果为vector< int >,vector< char >将可以使用memcpy进行拷贝;
但是vector这类的容器为一种类模板,对于类模板来说,其给的模板参数不一定一定就是内置类型,也有可能出现自定义类型;
就如使用vector< vector< int > >来说,最外层的模板参数为一个自定义类型,而内层的模板参数为一个内置类型int;

在这里插入图片描述
而如果在这里使用了memcpy进行原数据到新空间的拷贝将会怎么做;
在这里插入图片描述
表面上这里进行了拷贝,但实际上,进行了深拷贝的只有最外层;
对于内层而言只是使用了memcpy将对应的对象进行拷贝;
也就是说,这里出现了指针指向同一块空间的问题;

在这里插入图片描述
而若是在这种情况下则会出现重复析构的问题;


解决办法

在这种情况下只能摒弃以往的使用memcpy进行数据拷贝,并使用赋值进行拷贝;
以拷贝构造为例:

vector(const vector<T>& v){_start = new T[v.size()];for(size_t i = 0;i<v.size();++i){_start[i] = v._start[i];//若是自定义类型将会去调用它的赋值重载}_finish = _start + v.size();_end_of_storage = _start + v.capacity();
}

相关文章:

「C++之STL」关于在模拟实现STL容器中的深浅拷贝问题

文章目录 前言杨辉三角深浅拷贝问题模拟实现的vector对题目杨辉三角引发的程序崩溃原因解决办法 前言 在学习STL容器中,不仅需要学会容器的使用,同时也需要了解容器的大体框架以及各个函数的模拟实现才能更好的去了解这个容器; 杨辉三角 在LeetCode中有一道这样的题目,给定一…...

文件内容显示

目录 1.浏览普通文件 1.1. 文件内容查看 1.1.1. cat 命令 例&#xff1a; 1.1.2 扩展tac命令&#xff1a; 1.1.3. more 命令 1.1.4. less命令 1.1.5. head命令 1.1.6. tail命令 1.2. 文件属性信息查看 1.2.1. file 命令 1.2.2. stat 命令 2. 文件内容过滤…...

Milvus+Attu

Milvus 1.下载 https://github.com/milvus-io/milvus/releases/wget https://github.com/milvus-io/milvus/releases/download/v2.3.0/milvus-standalone-docker-compose.yml下载milvus-standalone-docker-compose version: 3.5services:etcd:container_name: milvus-etcdim…...

LeetCode算法二叉树—226. 翻转二叉树

目录 226. 翻转二叉树 代码&#xff1a; 运行结果&#xff1a; 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入…...

AI项目十:Swin Transformer目标检测环境搭建

若该文为原创文章&#xff0c;转载请注明原文出处。 Swin Transformer是做什么的这里不做介绍&#xff0c;主要是记录下学习的全过程&#xff0c;Swin Transformer在搭建和训练的过程中&#xff0c;折腾了很久&#xff0c;主要是在折腾环境。 一、AutoDL租用实例 个人没有GP…...

【IPC 通信】信号处理接口 Signal API(5)

收发信号思想是 Linux 程序设计特性之一&#xff0c;一个信号可以认为是一种软中断&#xff0c;通过用来向进程通知异步事件。 本文讲述的 信号处理内容源自 Linux man。本文主要对各 API 进行详细介绍&#xff0c;从而更好的理解信号编程。 kill(2) 遵循 POSIX.1 - 2008 1.库 …...

Arduino PLC IDE

Arduino PLC IDE MCU单片机进入全新的PLC领域概述需要的硬件和软件下一步操作1. Arduino PLC IDE Tool Setup2. Arduino PLC IDE Setup3. Project Setup4. Download the Runtime5. Connect to the Device6. License Activation with Product Key (Portenta Machine Control) 结…...

记录使用iText7查找PDF内容关键字坐标,加盖电子签名、印章

一、前言 项目以前签字都是由C端那边进行合成操作&#xff0c;最近项目要求把那块功能&#xff0c;由后端进行实现&#xff0c;其中包含坐标、关键字、任意位置进行签字操作&#xff0c;坐标是最容易实现的&#xff0c;曾经也写过类似的功能在&#xff08;添加图片印章到PDF&a…...

Java8实战-总结37

Java8实战-总结37 默认方法不断演进的 API初始版本的 API第二版 API 默认方法 传统上&#xff0c;Java程序的接口是将相关方法按照约定组合到一起的方式。实现接口的类必须为接口中定义的每个方法提供一个实现&#xff0c;或者从父类中继承它的实现。但是&#xff0c;一旦类库…...

【超详细】前段开发之详细的Vue3入门教程,特别适合小白系统学习,入门到熟练使用Vue看这一篇就够了!

前言&#xff1a; 这篇文章更加侧重的是Vue3不同于Vue2的知识点&#xff0c;如果学习Vue2请看下面这篇文章 Vue2详细系统入门教程 11.2 Vue3 声明&#xff1a;图片资源来自于黑马程序员公开学习资料 本人在学习当中&#xff0c;详细整理了笔记&#xff0c;供大家参考学习 1…...

【深度学习】ONNX模型多线程快速部署【基础】

【深度学习】ONNX模型CPU多线程快速部署【基础】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】ONNX模型CPU多线程快速部署【基础】前言搭建打包环境python多线程并发简单教程基本教程ONNX模型多线程并发 打包成可执行文件总结 前…...

Python 同、异步HTTP客户端封装:性能与简洁性的较量

一、前言 引入异步编程趋势&#xff1a;Python的异步编程正变得越来越流行。在过去&#xff0c;同步的HTTP请求已经不足以满足对性能的要求。异步HTTP客户端库的流行&#xff1a;目前&#xff0c;有许多第三方库已经实现了异步HTTP客户端&#xff0c;如aiohttp和httpx等。然而…...

无代码赋能数字化,云表搭桥铺路链接“数据孤岛”

什么是信息孤岛 企业数字化转型过程中&#xff0c;信息孤岛是一个突出的问题。这种情况发生的原因是&#xff0c;企业内部使用了多种应用软件&#xff0c;时间一长&#xff0c;员工在不同的系统中积累了大量的企业数据资产。然而&#xff0c;由于这些系统之间的数据无法互通&am…...

无需公网IP,实现公网SSH远程登录MacOS【内网穿透】

目录 前言 1. macOS打开远程登录 2. 局域网内测试ssh远程 3. 公网ssh远程连接macOS 3.1 macOS安装配置cpolar 3.2 获取ssh隧道公网地址 3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址 4.1 保留一个固定TCP端口地址 4.2 配置固定TCP端口地址 5. 使用固定TCP端…...

网络爬虫学习笔记 1 HTTP基本原理

HTTP原理 ~~~~~ HTTP&#xff08;Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一种使用最为广泛的网络请求方式&#xff0c;常见于在浏览器输入一个地址。 1. URI和URL URL&#xff08;Universal Resource Locator&#xff0c;统一资源定位器&…...

113. 路径总和ii

力扣题目链接(opens new window) 给定一个二叉树和一个目标和&#xff0c;找到所有从根节点到叶子节点路径总和等于给定目标和的路径。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树&#xff0c;以及目标和 sum 22&#xff0c; 在路径总和题目的基础上&…...

百度APP iOS端包体积50M优化实践(六)无用方法清理

一、前言 百度APP包体积经过一期优化&#xff0c;如无用资源清理&#xff0c;无用类下线&#xff0c;Xcode编译相关优化&#xff0c;体积已经有了明显的减少。但是优化后APP包体积在iPhone11上仍有350M的空间占用。与此同时百度APP作为百度的旗舰APP&#xff0c;业务迭代非常多…...

MySQL了解视图View (视图篇 一)

视图View是什么&#xff1f; MySQL的视图是一种虚拟表&#xff0c;它是基于一个或多个表的查询结果构建而成的。视图并不实际存储数据&#xff0c;而是根据定义的查询逻辑动态生成结果。 ----------------------------------- 视图的特点&#xff1a; - 虚拟表&#xff1a;…...

使用applescript自动化trilium的数学公式环境

众所周知&#xff0c;trilium什么都好&#xff0c;就是对数学公式的支持以及markdown格式的导入导出功能太拉了&#xff0c;而最拉的时刻当属把这两个功能结合起来的时候&#xff1a;导入markdown文件之后&#xff0c;原来的数学公式全没了&#xff0c;需要一个一个手动用ctrlm…...

idea中maven项目打包成jar,报错没有主清单属性解决方法

使用idea自带的打包可能会出现一下问题 在pom.xml中引入下面的依赖&#xff0c;即可解决 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions&…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...