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

C++笔记之动态数组的申请和手动实现一个简单的vector

C++笔记之动态数组的申请和手动实现一个简单的vector

code review!

文章目录

  • C++笔记之动态数组的申请和手动实现一个简单的vector
    • 1.C语言中动态数组的申请与使用
    • 1.动态数组的申请
      • 使用`new`和`delete`
      • 使用`std::vector`
    • 1.std::vector的底层实现
    • 2.手动实现一个简单的vector:使用一个指向动态分配的数组的指针来存储元素模拟vector的基本行为

1.C语言中动态数组的申请与使用

在C语言中,可以使用malloc函数来动态申请内存以创建动态数组,并使用free函数来释放这些内存。以下是在C语言中创建和使用动态数组的基本示例:
在这里插入图片描述

代码

#include <stdio.h>
#include <stdlib.h>int main() {int size;printf("Enter the size of the dynamic array: ");scanf("%d", &size);// 使用malloc函数分配动态数组内存int *dynamicArray = (int *)malloc(size * sizeof(int));// 检查内存分配是否成功if (dynamicArray == NULL) {printf("Memory allocation failed.\n");return 1; // 返回错误码}// 初始化动态数组的元素for (int i = 0; i < size; i++) {dynamicArray[i] = i * 2;}// 访问和使用动态数组的元素for (int i = 0; i < size; i++) {printf("%d ", dynamicArray[i]);}// 释放动态数组内存free(dynamicArray);return 0;
}

在上述示例中,首先使用malloc函数分配了一块内存,该内存可以存储sizeint类型的元素。然后,通过循环初始化和使用动态数组的元素。最后,使用free函数释放分配的内存以防止内存泄漏。

请注意,使用mallocfree来管理内存需要特别小心,确保在不再需要动态数组时释放内存,以免出现内存泄漏。此外,动态数组的内存大小必须在运行时明确定义,并且需要手动处理分配和释放内存,这可能会引入错误,因此要特别小心。如果可能的话,推荐使用C++中的std::vector或C语言的动态数组分配方式,如allocastrdup,以减少手动内存管理的复杂性。

1.动态数组的申请

在C++中,可以使用new运算符来动态申请数组,并使用delete运算符来释放它们。此外,C++11引入了std::vector,它是一个动态数组的封装,提供了更方便和安全的方法来管理动态数组。下面分别介绍使用newstd::vector的方法来创建和使用动态数组。

使用newdelete

在这里插入图片描述

代码

#include <iostream>int main() {int size;std::cout << "Enter the size of the dynamic array: ";std::cin >> size;// 通过new运算符分配动态数组int* dynamicArray = new int[size];// 初始化动态数组的元素for (int i = 0; i < size; i++) {dynamicArray[i] = i * 2;}// 访问和使用动态数组的元素for (int i = 0; i < size; i++) {std::cout << dynamicArray[i] << " ";}// 释放动态数组内存delete[] dynamicArray;return 0;
}

使用new分配动态数组后,不要忘记使用delete[]释放内存,以防止内存泄漏。

使用std::vector

使用std::vector可以更方便地管理动态数组,无需手动分配和释放内存:

#include <iostream>
#include <vector>int main() {int size;std::cout << "Enter the size of the dynamic array: ";std::cin >> size;// 使用std::vector创建动态数组std::vector<int> dynamicArray(size);// 初始化动态数组的元素for (int i = 0; i < size; i++) {dynamicArray[i] = i * 2;}// 访问和使用动态数组的元素for (int i = 0; i < size; i++) {std::cout << dynamicArray[i] << " ";}return 0;
}

std::vector会自动处理内存分配和释放,使得代码更加安全和易维护。

无论您选择使用newdelete还是std::vector,都要确保正确管理动态数组的内存,以防止内存泄漏和访问越界错误。

1.std::vector的底层实现

C++中的vector是标准库中的一个动态数组容器,它提供了动态大小的数组,类似于C数组,但它具有自动管理内存的功能,可以动态增加或减少数组的大小。vector的底层实现通常是使用动态分配的数组,以及一些成员函数来管理这个数组的大小和元素。

下面是vector的一些常见底层实现细节:

  1. 动态分配的数组:vector内部通常使用一个指向动态分配的数组的指针来存储元素。这个数组的大小可以根据vector中存储的元素数量动态调整。当元素数量超过当前数组的容量时,vector会分配一个更大的数组,将元素从旧数组复制到新数组,然后释放旧数组。

  2. 容量(Capacity)和大小(Size):vector有两个重要的属性,容量和大小。容量表示当前数组的大小,而大小表示vector中实际存储的元素数量。容量通常大于或等于大小,因为vector可能会提前分配一些额外的空间,以减少频繁重新分配内存的开销。

  3. 动态调整容量:当vector的大小超过容量时,它会重新分配更大的内存块,并将元素从旧数组复制到新数组。这通常涉及到内存分配和复制操作,这可能会导致性能开销。为了减小重新分配的频率,vector通常会分配比当前大小更多的额外空间,以避免在每次插入元素时都重新分配内存。

  4. 内存管理:vector负责动态内存的分配和释放,以确保内存的正确管理。当vector不再需要某个内存块时,它会调用delete[]allocator::deallocate来释放内存。

  5. 迭代器:vector提供了迭代器,用于访问容器中的元素。迭代器是指向容器中元素的指针或对象,允许你遍历vector的内容。

总之,vector的底层实现是基于动态分配的数组,它使用内部指针来管理内存,并提供了各种方法来操作容器中的元素,包括插入、删除、访问等。这些实现细节在C++标准库中是隐藏的,因此你可以方便地使用vector而无需担心底层实现的细节。

2.手动实现一个简单的vector:使用一个指向动态分配的数组的指针来存储元素模拟vector的基本行为

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <iostream>class MyVector {
public:MyVector() : data(nullptr), size(0), capacity(0) {}void push_back(int value) {if (size >= capacity) {// 如果当前大小超过容量,需要重新分配更大的内存int new_capacity = (capacity == 0) ? 1 : capacity * 2;int* new_data = new int[new_capacity];// 将数据从旧数组复制到新数组for (int i = 0; i < size; i++) {new_data[i] = data[i];}// 释放旧数组的内存delete[] data;// 更新指针和容量data = new_data;capacity = new_capacity;}// 在数组末尾添加新元素data[size] = value;size++;}int at(int index) {if (index >= 0 && index < size) {return data[index];} else {std::cerr << "Index out of range!" << std::endl;return -1;}}int getSize() {return size;}~MyVector() {delete[] data; // 释放动态分配的内存}private:int* data;      // 指向动态分配的数组的指针int size;       // 当前元素数量int capacity;   // 当前容量
};int main() {MyVector vec;// 向自定义的vector中添加一些元素for (int i = 1; i <= 10; i++) {vec.push_back(i * 10);}// 访问元素并打印for (int i = 0; i < vec.getSize(); i++) {std::cout << "Element at index " << i << ": " << vec.at(i) << std::endl;}return 0;
}

相关文章:

C++笔记之动态数组的申请和手动实现一个简单的vector

C笔记之动态数组的申请和手动实现一个简单的vector code review! 文章目录 C笔记之动态数组的申请和手动实现一个简单的vector1.C语言中动态数组的申请与使用1.动态数组的申请使用new和delete使用std::vector 1.std::vector的底层实现2.手动实现一个简单的vector:使用一个指向…...

答题测评考试小程序的效果如何

在线答题系统是一种在线练习、考试、测评的智能答题系统&#xff0c;适用于企业培训、测评考试、知识竞赛、模拟考试等场景&#xff0c;管理员可任意组题、随机出题&#xff0c;答题者成功提交后&#xff0c;系统自动判分。 多种题目类型&#xff0c;两种答题模式 练习模式&a…...

树上贪心+生成树贪心:1104T3

<47.92.197.167:5283/contest/425/problem/3> 根据 n n n 奇偶性可以推断答案 合法解只需要在任何一棵生成树上构造即可 贪心肯定要在最大生成树上 然后从前往后看一条未选的边能不能选即可 #include<bits/stdc.h> using namespace std; #ifdef LOCAL#define …...

MySQL进阶之性能优化与调优技巧

数据库开发-MySQL 1. 多表查询1.1 概述1.1.2 介绍1.1.3 分类 1.2 内连接1.3 外连接1.4 子查询1.4.1 介绍1.4.2 标量子查询1.4.3 列子查询1.4.4 行子查询1.4.5 表子查询 2. 事务2.1 介绍2.2 操作2.3 四大特性 3. 索引3.1 介绍3.2 结构3.3 语法 1. 多表查询 1.1 概述 1.1.2 介绍…...

MySQL EXPLAIN查看执行计划

MySQL 执⾏计划是 MySQL 查询优化器分析 SQL 查询时⽣成的⼀份详细计划&#xff0c;包括表如何连 接、是否⾛索引、表扫描⾏数等。通过这份执⾏计划&#xff0c;我们可以分析这条 SQL 查询中存在的 问题&#xff08;如是否出现全表扫描&#xff09;&#xff0c;从⽽进⾏针对优化…...

目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】机器视觉(最终篇)

目录 知识储备 杂散光 结构光 ■ 被动测距 ■ 主动结构光 图像分类技巧 增强...

redis教程 二 redis客户端Jedis使用

文章目录 Redis的Java客户端-JedisJedis快速入门创建工程&#xff1a;引入依赖&#xff1a;建立连接测试&#xff1a;释放资源Jedis连接池创建Jedis的连接池改造原始代码 Redis的Java客户端-SpringDataRedis快速入门导入pom坐标配置文件测试代码 数据序列化器StringRedisTempla…...

【数据开发】大数据平台架构,Hive / THive介绍

1、大数据引擎 大数据引擎是用于处理大规模数据的软件系统&#xff0c; 常用的大数据引擎包括Hadoop、Spark、Hive、Pig、Flink、Storm等。 其中&#xff0c;Hive是一种基于Hadoop的数据仓库工具&#xff0c;可以将结构化的数据映射到Hadoop的分布式文件系统上&#xff0c;并提…...

SOEM源码解析——ecx_init_context(初始化句柄)

0 工具准备 1.SOEM-master-1.4.0源码1 ecx_init_context函数总览 /*** @brief 初始化句柄* @param context 句柄*/ void ecx_init_context(ecx_contextt *context) {int lp;*(context->slavecount) = 0;/* clean ec_slave array */...

11.Z-Stack协议栈使用

f8wConfig.cfg文件 选择信道、设置PAN ID 选择信道 #define DEFAULT_CHANLIST 0x00000800 DEFAULT_CHANLIST 表明Zigbee模块要工作的网络&#xff0c;当有多个信道参数值进行或操作之后&#xff0c;把结果作为 DEFAULT_CHANLIST值 对于路由器、终端、协调器的意义&#xff1…...

设计模式—结构型模式之适配器模式

设计模式—结构型模式之适配器模式 将一个接口转换成客户希望的另一个接口&#xff0c;适配器模式使接口不兼容的那些类可以一起工作&#xff0c;适配器模式分为类结构型模式&#xff08;继承&#xff09;和对象结构型模式&#xff08;组合&#xff09;两种&#xff0c;前者&a…...

【LeetCode】187. 重复的DNA序列

187. 重复的DNA序列 难度&#xff1a;中等 题目 DNA序列 由一系列核苷酸组成&#xff0c;缩写为 A, C, G 和 T.。 例如&#xff0c;"ACGAATTCCG" 是一个 DNA序列 。 在研究 DNA 时&#xff0c;识别 DNA 中的重复序列非常有用。 给定一个表示 DNA序列 的字符串 …...

C++17中std::any的使用

类sdk:any提供类型安全的容器来存储任何类型的单个值。通俗地说&#xff0c;std::any是一个容器&#xff0c;可以在其中存储任何值(或用户数据)&#xff0c;而无需担心类型安全。void*的功能有限&#xff0c;仅存储指针类型&#xff0c;被视为不安全模式。std::any可以被视为vo…...

携手ChainGPT 人工智能基础设施 波场TRON革新 Web3 版图

近日,波场TRON与 Web3 人工智能基础设施服务商 ChainGPT 正式达成合作。通过本次合作,双方将进一步推动人工智能和区块链技术的融合,在实现优势互补的同时,真正惠及日常生活。 作为一站式的加密AI中心,ChainGPT 的人工智能工具需要进行大量计算,能耗高,而波场TRON采用的创新型…...

pdfH5实现pdf预览功能

1.引入 npm install pdfh5 2.使用 <view id"pdfBox" class""></view> showPdf(url) {this.pdfh5 new Pdfh5("", {URIenable: false,zoomEnanle: true,maxZoom: 2,pdfurl: url})this.pdfh5.on("complete", function(st…...

Redis的持久化机制

多级缓存使用到了一个装饰设计模式&#xff1a;相当于我不影响我之前缓存本身的代码&#xff0c;但是我可以对我的缓存去做增强&#xff0c;因此多级缓存就是采用装饰模式去实现的~&#xff01; 多级缓存可以采用装饰模式去重构~&#xff01; Redis当中的持久化机制&#xff…...

mac装不了python3.7.6

今天发现一个很奇怪的问题 但是我一换成 conda create -n DCA python3.8.12就是成功的 这个就很奇怪...

仿写知乎日报第三周

新学到的 本周新学习了FMDB数据库&#xff0c;并对Masonry的使用有了更近一步的了解&#xff0c;还了解了cell的自适应高度 FMDB数据库的介绍和使用&#xff1a;iOS——FMDB的介绍与使用 cell自适应高度和Mansonry自动布局 本周写了评论区&#xff0c;在写评论区的时候&…...

Godot Best practices

Get Forward Vector transform.x # 等价手算 var rad node.rotation var forward Vector2(cos(rad), sin(rad))Await and Unity Style Coroutine func coroutine(on_update: Callable, duration: float 1):var elapse_time 0while elapse_time < 1:elapse_time get_p…...

win10 + cmake3.17 编译 giflib5.2.1

所有源文件已经打包上传csdn&#xff0c;大家可自行下载。 1. 下载giflib5.2.1&#xff0c;解压。 下载地址&#xff1a;GIFLIB - Browse Files at SourceForge.net 2. 下载CMakeLists.txt 及其他依赖的文件 从github上的osg-3rdparty-cmake项目&#xff1a; https://github.…...

【rust/esp32】初识slint ui框架并在st7789 lcd上显示

文章目录 说在前面关于slint关于no-std关于dma准备工作相关依赖代码结果参考 说在前面 esp32版本&#xff1a;s3运行环境&#xff1a;no-std开发环境&#xff1a;wsl2LCD模块&#xff1a;ST7789V2 240*280 LCDSlint版本&#xff1a;master分支github地址&#xff1a;这里 关于s…...

精通Nginx(05)-http工作机制、指令和内置变量

http服务是Nginx最原始的服务,搞清楚其工作机制非常有利于弄懂nginx是如何工作的。 Nginx核心模块为ngx_http_core_module。 目录 http工作机制 配置结构 工作机制 http常用指令 http server listen server_name location 优先级 "/"的特殊用法 root/a…...

用于 GaN-HEMT 功率器件仿真的 TCAD 方法论

目录 标题&#xff1a;TCAD Methodology for Simulation of GaN-HEMT Power Devices来源&#xff1a;Proceedings of the 26th International Symposium on Power Semiconductor Devices & ICs(14年 ISPSD)GaN-HEMT仿真面临的挑战文章研究了什么文章的创新点文章的研究方法…...

Web3公链之Cosmos生态的项目Celestia

文章目录 Web3公链之Cosmos生态的项目&#xff1a;模块化区块链Celestia什么是CelestiaCelestia网络架构数据可用性问题有哪些可用的解决方案&#xff1f; 发展历史运行节点参考 Web3公链之Cosmos生态的项目&#xff1a;模块化区块链Celestia 什么是Celestia 官网&#xff1a…...

vue+prismjs 网页代码高亮插件

最近在使用wangEditor的过程中发现编辑器中代码块展示没有问题&#xff0c;但是预览编辑器中的内容样式丢失&#xff0c;看过wangEditor的文档后发现用到了Prism.js&#xff0c;现将使用的经验分享。 使用步骤 1、安装prismjs插件 // 1. 安装prismjs 插件 npm install prismj…...

【软件测试】其实远远不止需求文档这么简单

我们都知道&#xff0c;软件测试是一门依赖性很强的综合技术&#xff0c;软件测试工程师在施行自己的工作时&#xff0c;总是要依赖其他团队的产出。 比如&#xff0c;我们要依赖着需求团队给出的需求分析说明书来确定测试的方向&#xff0c;又要依赖开发团队产出的实际代码产品…...

SAP-PP-常用TCODE

PP主数据管理MM01/MM02物料主数据维护/修改 MM17物料主数据部分字段批量修改 /sapapo/mat1PPDS查看物料主数据 /sapapo/Res01PPDS查看资源主数据 BOM管理CS01/CS02维护/修改/删除BOM 超级BOM涉及到物料分类类型001 &#xff0c;CT04 创建特性&#xff0c;CL01 创建类 工作中…...

第六章认识Node.js服务器开发

目录 Node.js同步和异步编程 基本概念 执行方式 获取异步API的返回值 网页基础扩展 项目 Node.js同步和异步编程 基本概念 同步API(应用程序编程接口)是指只有当前API执行完毕后才能继续执行下一个API。形象的说同步模式就是一个服务员在某一个时间段内只服务一个客人…...

Ubuntu 增加服务 比如openfire

在Ubuntu上&#xff0c;可以使用systemd来管理和配置服务。下面是将命令添加为服务的一般步骤&#xff1a; 创建一个.service文件&#xff0c;该文件描述了您要添加的服务。打开终端&#xff0c;并使用以下命令创建一个新的服务文件&#xff1a; sudo nano /etc/systemd/syst…...

海康Visionmaster-全局变量:全局变量关联流程中具体 模块结果的方法

将视觉流程中模板匹配算法模块运行的结果数据&#xff1a;特征匹配点 X 关联全局变量 MatchResultX。 在流程运行的主界面中&#xff0c;按照下面 1&#xff0c;2&#xff0c;3&#xff0c;4 步骤操作&#xff0c;第一步选中算法模块&#xff0c;第二步择模块结果 Tab 页&#…...