「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 命令 例: 1.1.2 扩展tac命令: 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. 翻转二叉树 代码: 运行结果: 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入…...
AI项目十:Swin Transformer目标检测环境搭建
若该文为原创文章,转载请注明原文出处。 Swin Transformer是做什么的这里不做介绍,主要是记录下学习的全过程,Swin Transformer在搭建和训练的过程中,折腾了很久,主要是在折腾环境。 一、AutoDL租用实例 个人没有GP…...
【IPC 通信】信号处理接口 Signal API(5)
收发信号思想是 Linux 程序设计特性之一,一个信号可以认为是一种软中断,通过用来向进程通知异步事件。 本文讲述的 信号处理内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解信号编程。 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端那边进行合成操作,最近项目要求把那块功能,由后端进行实现,其中包含坐标、关键字、任意位置进行签字操作,坐标是最容易实现的,曾经也写过类似的功能在(添加图片印章到PDF&a…...
Java8实战-总结37
Java8实战-总结37 默认方法不断演进的 API初始版本的 API第二版 API 默认方法 传统上,Java程序的接口是将相关方法按照约定组合到一起的方式。实现接口的类必须为接口中定义的每个方法提供一个实现,或者从父类中继承它的实现。但是,一旦类库…...
【超详细】前段开发之详细的Vue3入门教程,特别适合小白系统学习,入门到熟练使用Vue看这一篇就够了!
前言: 这篇文章更加侧重的是Vue3不同于Vue2的知识点,如果学习Vue2请看下面这篇文章 Vue2详细系统入门教程 11.2 Vue3 声明:图片资源来自于黑马程序员公开学习资料 本人在学习当中,详细整理了笔记,供大家参考学习 1…...
【深度学习】ONNX模型多线程快速部署【基础】
【深度学习】ONNX模型CPU多线程快速部署【基础】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】ONNX模型CPU多线程快速部署【基础】前言搭建打包环境python多线程并发简单教程基本教程ONNX模型多线程并发 打包成可执行文件总结 前…...
Python 同、异步HTTP客户端封装:性能与简洁性的较量
一、前言 引入异步编程趋势:Python的异步编程正变得越来越流行。在过去,同步的HTTP请求已经不足以满足对性能的要求。异步HTTP客户端库的流行:目前,有许多第三方库已经实现了异步HTTP客户端,如aiohttp和httpx等。然而…...
无代码赋能数字化,云表搭桥铺路链接“数据孤岛”
什么是信息孤岛 企业数字化转型过程中,信息孤岛是一个突出的问题。这种情况发生的原因是,企业内部使用了多种应用软件,时间一长,员工在不同的系统中积累了大量的企业数据资产。然而,由于这些系统之间的数据无法互通&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(Hyper Text Transfer Protocol,超文本传输协议)是一种使用最为广泛的网络请求方式,常见于在浏览器输入一个地址。 1. URI和URL URL(Universal Resource Locator,统一资源定位器&…...
113. 路径总和ii
力扣题目链接(opens new window) 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树,以及目标和 sum 22, 在路径总和题目的基础上&…...
百度APP iOS端包体积50M优化实践(六)无用方法清理
一、前言 百度APP包体积经过一期优化,如无用资源清理,无用类下线,Xcode编译相关优化,体积已经有了明显的减少。但是优化后APP包体积在iPhone11上仍有350M的空间占用。与此同时百度APP作为百度的旗舰APP,业务迭代非常多…...
MySQL了解视图View (视图篇 一)
视图View是什么? MySQL的视图是一种虚拟表,它是基于一个或多个表的查询结果构建而成的。视图并不实际存储数据,而是根据定义的查询逻辑动态生成结果。 ----------------------------------- 视图的特点: - 虚拟表:…...
使用applescript自动化trilium的数学公式环境
众所周知,trilium什么都好,就是对数学公式的支持以及markdown格式的导入导出功能太拉了,而最拉的时刻当属把这两个功能结合起来的时候:导入markdown文件之后,原来的数学公式全没了,需要一个一个手动用ctrlm…...
idea中maven项目打包成jar,报错没有主清单属性解决方法
使用idea自带的打包可能会出现一下问题 在pom.xml中引入下面的依赖,即可解决 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions&…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
