讨论标准模板库std::vector的容量/大小及其内存增量

C++中size()与length()的区别与选择:从字符串到容器的类型安全实践 在C++编程中,理解容器与字符串的长度/大小获取方式是编写健壮代码的基础。标准库通过提供统一的接口来确保类型安全与一致性,其中size()作为所有STL容器的通用方法,返回元素数量的无符号类型size_t,而length()则更侧重于具有线性长度语义的对象(如字符串)。这种设计不仅关乎历史兼容性,更影响着代码的泛化能力和可移植性。从原理上看,size()体现了STL容器接口的一致性哲学,而length()则保留了直观的语义表达。在工程实践中,统一使用size()能减少认知负担,提升模板代码的通用性,但需警惕 阅读详情

首先解释一下容量/大小的区别:
  std::vector::capacity() : 指容器的能容纳多少个。
  std::vector::size() : 指容器当前已装多少个。
明白上面的意思思路就清晰多了。

 

这几天有同事用vector的时候遇到问题,说是当push_back以后,以前引用了vector的地址就不能访问。
造成以前引用的地址不能使用的原因估计大家都知道。
主要原因是vector有一个内存增量机制。


内增量机制是:为了满路容器的连续内存访问,当vector发现自己内存不够用,就需要重新申请内存,
然后复制旧的数据过去,删除旧的数据,重新指向新的数据地址。
当这个复制过程一结束的时候,以前引用了下标为0的vector内存地址就会不再是该数据地址了,
已被复制走的原有数据已删除成为野内存。
这时需要重去引用一次。

 

关于这个增量机制网上有多种说法,
  1说法:按原有尺寸的2倍增长,即:new_capacity = capacity_size * 2;
  2说法:按原有尺寸的50%增加,即:new_capacity = capacity_size / 2 + capacity_size;
  3说法:按数据尺寸倍数增长,即 sizeof(class) * 2;
  4说法:按字节来,即: (1024)/sizeof(class);


就此问题,我专门去看了看vector的原代码。得到的结果是:2说法正确。
这点可以从std::vector::_Insert_n(iterator, size_type, const _Ty&)的原代码中可以看出:

// 如果容量 < 大小 + 新数量增量
else if (_Capacity < size() + _Count)
{
  // 容量 = 容量 + 容量 / 2;
  _Capacity = max_size() - _Capacity / 2 < _Capacity ? 0 : _Capacity + _Capacity / 2; 
  // 容量 < 大小 + 新增数量
  if (_Capacity < size() + _Count)
    // 容量 = 大小 + 新增数量
    _Capacity = size() + _Count;
  // 申请新内存
  pointer _Newvec = this->_Alval.allocate(_Capacity);
  // 开始引用地址
  pointer _Ptr = _Newvec;
  // 复制与删除过程
  ......
}

 

那么如何解决我即想引用vector的地址又不需要经常去刷新该地址呢?
同时又解决掉vector的复制问题,也解决掉有些类的复制构造?
方法还是有的。
这里就有前面提到的容量/大小的因素了。
容量必然大于大小,是肯定的,即:capacity >= size;

 

方法1:
  创建std::vector容器,并调用std::vector::reserve(int n);
  告诉vector的直接增加n个数据并分配内存,
  这样的话push_back数量在n以内,引用的地址不会发生变化。vector内存也没有改变
  但如果事先告诉n的程序,这种方法是最好的。
  例:
    std::vector< int > vA;
    vA.reserve(10);
    vA.push_back(7);
    vA.push_back(6);
    vA.push_back(2);
    vA.push_back(9);
    int* pAddress = &vA[0];


方法2:
  通过构造函数告诉该容量容量
  各种带参数构造类似,这里不多举例
  例:
    std::vector< int > vA(10);
    int* pAddress = &vA[0];
    pAddress[0] = 7; // 等于 vA[0] = 7;
    pAddress[1] = 6; // 等于 vA[1] = 6;
    pAddress[2] = 2; // 等于 vA[2] = 2;
    pAddress[3] = 9; // 等于 vA[3] = 9;


方法3:
  与方法1方法一样。只是调用函数是:std::vector::resize(int n);

 

再说说resize与reserve的区别
resize:新的大小 < 现有大小,会删除多余的部分
        新的大小 > 现有大小,会在现有尺部插入新的数据,这时就有可能造成容量变化
        其它情况不操作。
reserve:当前容量 < 传入容量,会根据新的容量创建内存,并复制。
         当前容量 > 传入容量,不理踩
         其它情况不操作。

C++游戏开发入门:从SFML实战到核心架构解析 游戏开发的核心在于理解其底层运行机制,而非仅仅使用现成的引擎工具。游戏循环是实时应用的心脏,它遵循“处理事件、更新逻辑、渲染绘制”的基本流程,确保游戏世界的持续运转。面向对象编程(OOP)是构建复杂、可维护游戏系统的关键技术,它通过封装、继承和多态性,将游戏中的角色、物体和行为抽象为可管理的类,例如在《Pong》项目中创建`Bat`和`Ball`类。这种设计模式的价值在于提升代码的复用性和组织性,为管理《Zombie Arena》中大量的僵尸对象或实现《Thomas Was Late》的组件化架构奠定基础。 阅读详情

相关推荐

C++内存泄漏全解析:从原理到实战,智能指针与RAII的防御之道

内存管理是编程语言的核心机制之一,它决定了程序如何高效、安全地使用计算机内存资源。其基本原理是程序在运行时向操作系统申请内存,并在使用完毕后及时释放,以供其他任务复用。若管理不当,未释放的内存会不断累积,最终导致程序因内存耗尽而崩溃,这就是内存泄漏。在C++这类手动管理内存的语言中,内存泄漏尤为常见且危害巨大,直接影响程序的稳定性和性能。其技术价值在于,通过自动化的资源管理范式,可以显著降低人为错误,提升代码的健壮性和可维护性。典型的应用场景包括需要长期运行的后端服务、嵌入式系统和大型桌面应用程序,这些场景

weixin_30363509的博客 433

C++ std::vector::size()函数(返回向量中的元素数量)

文章目录cppman std::vector::size上面文档中的代码示例 cppman std::vector::size std::vector::size(3) C++ Programmer's Manual std::vector::size(3) NAME std::vector::

Dontla的博客 1万+

C语言到C++过渡指南:掌握面向对象、STL与刷题技巧

编程语言的学习往往离不开指针、内存管理和数据结构等基础概念。C语言以面向过程为核心,开发者需要手动管理内存、处理字符串和数组,这类操作在工程实践中较为繁琐。C++作为C语言的扩展,在保留底层操控能力的同时,引入了类、封装、继承与多态等面向对象特性,并提供了标准模板库(STL)来简化容器、算法和迭代器的使用。理解虚函数、智能指针和拷贝控制等机制,有助于写出更安全、高效的代码。在在线评测平台(如PTA、GESP)刷题时,掌握字符串逆序、快速排序等常见题型的C++写法,能显著提升解题效率。无论是嵌入式开发、游戏引

weixin_34406086的博客 288

std::vector的size()与int类型的比较

使用vec.size() - 1需要注意,vec.size()是无符号的整数。

qq_25635285的博客 727

Win11内核隔离无法打开的解决方案详解

内核隔离问题的解决需遵循"先硬件后软件"的排查原则,90%以上的案例可通过驱动清理或外设断开解决。对于必须禁用该功能的用户,建议定期使用Windows Defender进行全盘扫描,并保持系统更新至最新版本。技术决策需在安全性和兼容性之间取得平衡,本文提供的多维解决方案可帮助用户构建更稳定的Windows 11使用环境。

mmoo_python的博客 4830

linux下docker 部署onlyoffice社区版

Onlyoffice 是一款功能丰富的在线 Office 工具,类似 WPS 和 微软的 Office 套件。OnlyOffice Workspace 是由 OnlyOffice 推出的基于云计算的企业级在线协作办公平台,由文档服务(Document Server)、控制面板(Control Panel)、社区服务(Community Server)和邮件服务(Mail Server)四个组件构成,提供了文档、项目、成员、邮件等功能模块,支持文档多人协作、历史版本控制等功能,旨在帮助用户提高工作效率和工作质

axiaowua的博客 2382

[C++]std::vector中的size、capacity、resize、reserve

C++容器,std::vector中的size、capacity、resize、reserve的区别和用法。

qq_40939614的博客 2204

本地服务器搭建Uptime Kuma网站监控服务

本文主要介绍如何在Linux系统中一键部署Uptime Kuma运维监控服务,并将这个服务映射至公网实现随时随地远程访问。如果您像我一样在服务器上托管了多个网站,并且没有足够的时间来手动检查每个网站的在线状态,那么当出现问题时,您可能无法及时收到通知来处理这些问题。因此,搭建一个在线监控服务是很有必要的,它可以在状态异常时提醒您,以便您能够及时处理问题,确保网站的稳定性和可用性。监控服务有很多,我最终选择了Uptime Kuma,因为Uptime Kuma是开源免费的,

Tiam_cr的博客 1824

【C++】STL——vector的有关空间的函数介绍和使用、size和capacity函数、resize和reserve函数

SLT、vector的使用、vector空间增长问题、size(获取数据个数)capacity (获取容量大小)empty (判断是否为空)resize (改变vector的size)reserve (改变vector的capacity)

Crocodile1006的博客 3564

学习海康VisionMaster之顶点检测

2:应用场景:海康VisionMaster的顶点检测功能在工业视觉检测中具有广泛的应用场景,尤其在精密制造、电子元件检测和机械加工等领域,其通过高精度定位物体的关键点(如角点、交点或边缘顶点)来实现自动化测量与质量控制。基本参数这里就是画ROI,设定跟踪参数和之前的工具是一样的方法,这里画的方向需要注意,如下图所示,边缘的扫描方向正好对应需要查找的边缘点。一个不是很规则的物体需要检测一个凸台的顶角坐标,其实靠边缘与边缘交点是不太稳定的,如下图所示,边缘很短,很容易产生误抓边缘。1:什么是顶点检测?

yuhouxiyang的专栏 1526

Python量化交易实战:从零搭建你的第一个多因子选股模型(附完整代码)

本文是一份详细的Python量化交易入门实战指南,手把手教你从零搭建第一个多因子选股模型。内容涵盖环境配置、数据获取、因子挖掘与有效性检验、多因子合成以及完整的策略回测与绩效评估,并附有可直接运行的完整代码,帮助初学者快速掌握量化交易的基本概念与实践流程。

resnet7explorer的博客 936

C++ std::vector: vector中元素的存储方式 size、capacity、reserve、resize的使用

1. vector的对象的存储方式 为了支持随机访问,vector将元素连续存储–每个元素紧挨着前一个元素存储。容器中元素是连续存储的,且容器的大小是可变的。 在容器中增加元素时。vector根据存储元素的大小,在内存上申请一个空间,用于存储数据,空间的大小通常会大于所存储元素的实际大小,并且预留出一部分预留的空间,以便再次增加数据时,可以不用重新开辟空间。 当容器再次增加新的元素后,首先判断预留的空间是否够用,如果够用直接在预留空间中存储。如果预留的空间不够,需要在内存中开辟一整块新的更大的空间,并将ve

休息一下接着来的博客 3225

手把手教你用芯驰X9HP驱动MAX96755/MAX96752点亮智能座舱仪表屏(附完整寄存器配置表)

本文详细介绍了如何使用芯驰X9HP驱动MAX96755/MAX96752实现智能座舱仪表屏的完整开发流程,包括硬件架构解析、关键寄存器配置、Linux BSP集成及调试技巧。通过实战指南和完整寄存器配置表,帮助开发者快速掌握驱动开发核心技术,提升智能座舱系统的显示性能与稳定性。

weixin_30879169的博客 526

C++高效内存管理秘诀:动态数组与链表性能对决(附压测代码)

掌握C++容器性能对比秘诀,提升程序效率。深入剖析动态数组与链表在不同场景下的内存开销与访问速度,结合压测代码揭示适用时机。优化内存管理,显著提升运行性能,值得收藏。

CodeTrick的博客 1081

闲人闲谈PS之一项目库存跨公司业务STO解决方案--SAP闲人的开篇

写这篇文章之前,简单说一下发这篇文章的动机。也算是在SAP这一行干了快10多年,在对一个模块了解越来越深入,越发觉自己的SAP知识浅薄。总的来说,和多数顾问一样,对于**标准功能**的应用业务场景理解还是存在或多或少的知识盲区。 因为一个偶然,看到SAP团子君的文章,分享了很多干货文章。这也是自己一直想做的时候,不管水平高低与否,分享本身就意味着提升。好了废话不多说,先在优快云上发一篇吧,困惑自己将近10年的问题的解决方案。 业务场景:在项目型企业中,通常会有这样的业务,母公司和客...

SAP闲人的博客 9269

在 MATLAB/Simulink 中构建一个卫星间激光通信链路的完整仿真系统

摘要: 本文通过Simulink详细演示了卫星间激光通信系统的建模过程,重点分析其在10Gbps高速率、2000km距离下的性能。系统设计涵盖PAM-4调制、自由空间信道建模(路径损耗、指向误差、多普勒效应)、APD探测及链路预算计算,并给出典型场景下18.5dB SNR、1e-9误码率的仿真结果。针对激光通信的μrad级指向精度挑战,提出AI辅助跟踪、混合RF/激光等优化策略,为未来太空高速组网提供可扩展的仿真框架。所需工具箱包括Communications Toolbox和Aerospace Toolb

xiaoheshang_123的博客 384

C++ std::string 深度解析:从内存管理到性能优化的完整指南

在C++编程中,字符串处理是基础且核心的技术环节。其原理基于动态内存管理和RAII(资源获取即初始化)原则,通过封装字符数组自动处理内存分配与释放,从而避免手动管理内存的复杂性和缓冲区溢出等安全隐患。这一设计带来了显著的技术价值:不仅提升了代码的安全性和可维护性,还通过短字符串优化(SSO)等机制优化了性能。在实际应用场景中,无论是数据清洗、日志解析还是日常的文本操作,高效且安全的字符串处理都至关重要。本文聚焦于C++标准库中的`std::string`,深入探讨其内部实现、内存布局、常用操作及性能陷阱,并

weixin_34049948的博客 334

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C++ 基础知识(三)

C++ 的核心是其标准模板库STL),它代表了一组重要的数据结构和算法,有助于简化程序员的任务并提高代码效率。STL 的组件是参数化的,因此它们可以被以不同的方式重用和组合。STL 主要由容器类、迭代器和算法组成。容器用于存储特定类型的元素集合。通常,容器的类型是一个模板参数,它允许相同的容器类支持任意元素。有几个容器类,每个类都有不同的特性和功能。迭代器用于遍历容器中的元素。迭代器为程序员提供了一个简单且通用的接口来访问不同类型的容器。

龙哥盟 802

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C++ string类模拟实现:从内存管理到运算符重载的深度解析

在C++编程中,内存管理是核心基础概念之一,它要求开发者手动控制动态内存的申请与释放,以避免内存泄漏和重复释放等问题。其原理在于通过new和delete运算符在堆上分配和回收内存,这是理解C++资源管理模型的关键。这一技术的价值在于能够构建高效、可控的数据结构,如动态数组和字符串。应用场景广泛,从基础容器实现到高性能系统开发都离不开精细的内存控制。本文聚焦于通过模拟实现string类这一经典案例,深入探讨深浅拷贝、类的三大件(拷贝构造、拷贝赋值、析构)以及运算符重载等核心机制,帮助开发者从根本上掌握C++面

jackleechina2011212的博客 138

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C++手动实现栈:从数组与链表对比到内存管理实战

栈(Stack)作为一种基础的数据结构,遵循后进先出(LIFO)的核心原理,是理解计算机内存管理与程序执行流程的关键。其实现通常基于数组或链表两种底层结构,数组实现凭借连续内存存储和缓存友好性,在访问速度上具有优势;链表实现则通过动态节点分配,提供了真正的弹性容量。在C++工程实践中,手动实现栈不仅是对指针操作和类封装的深度练习,更是理解**内存管理**与**异常安全**的绝佳场景。无论是函数调用栈、表达式求值,还是浏览器的前进后退功能,栈的应用都极为广泛。通过对比动态数组栈和链表栈的性能差异,并深入探讨拷

cunfuxiao7305的博客 300

基于C++11线程池相关知识点与问题

本文详细解析了一个C++线程池的实现,重点探讨了其工作流程和关键技术点。线程池通过任务队列管理用户提交的任务,使用智能指针确保内存安全,通过条件变量实现线程同步。文章深入分析了相关C++11特性,包括智能指针、std::function、右值引用等,并解释了虚函数和模板在多态实现中的应用。特别介绍了自实现的Any、Result和Semaphore类来解决异步编程中的类型擦除和线程同步问题。

2501_91719039的博客 171

孙鑫C++教程深度解析:从内存模型到STL实战的编程内功修炼

C++作为一门支持面向对象与泛型编程的系统级语言,其核心在于对计算机内存和资源的精细控制。理解其内存模型、面向对象思想及标准库机制,是掌握高性能软件开发的基石。通过剖析经典教程体系,可以系统构建从语法基础、类与对象设计,到标准模板库应用的完整知识脉络。其中,智能指针和STL容器等现代C++特性,极大地提升了资源管理的安全性与开发效率。这些技术广泛应用于游戏引擎、高频交易及嵌入式系统等对性能与可靠性要求极高的场景。本文结合孙鑫C++全20讲教程,深入探讨了内存对齐、深拷贝与浅拷贝等关键热词,并解析了迭代器失效

读书、思考、生活 429

Unity3DTraining 面试题整理:Unity 游戏开发进阶面试全攻略(Lua / C / C++ / Unity / 算法 / 网络 / 设计模式)

> **导读**:本文以 [Doc/马三的面试题整理.md](https://link.gitcode.com/i/1e2661938046554cf4b53665647ea528) 为骨架,系统梳理 Unity 客户端开发岗位面试中的高频考点,涵盖 Lua、C#、C++、Unity 引擎、算法与 3D 数学、网络通信、设计模式七大板块,并对每一道题给出可复述的完整答案。文章同时以 Unity3D

gitblog_00845的博客 995

C++与C语言核心差异解析:从编程范式到现代特性

编程语言的核心差异往往源于其设计哲学与编程范式。过程式编程以函数和数据流为核心,强调对硬件的直接控制,适合底层系统开发。而面向对象编程通过封装、继承和多态等机制,将数据与操作绑定,提升了代码的模块化和复用性。在此基础上,泛型编程进一步实现了类型无关的算法抽象,增强了代码的通用性。这些编程范式的演进,本质上是为了应对日益复杂的软件工程挑战,如代码复用、资源管理和系统可维护性。C++作为一门多范式语言,融合了过程式、面向对象和泛型编程,同时通过RAII(资源获取即初始化)和智能指针等机制,在保持高性能的同时显著

weixin_34393428的博客 427

C++ STL deque源码解析:为何成为stack与queue的默认底层容器

在C++标准模板库(STL)中,容器适配器如stack和queue是构建高效数据结构的基础组件。它们本身并不直接管理内存,而是通过封装一个底层容器来实现特定接口。这种设计模式的核心在于选择既能满足操作复杂度要求,又能平衡内存与性能的底层数据结构。deque(双端队列)采用分段连续的存储策略,通过一个中央控制器管理多个固定大小的内存块(缓冲区),从而在头部和尾部实现了平摊O(1)时间复杂度的插入与删除操作,同时支持高效的随机访问。这种设计巧妙地规避了vector扩容时整体数据搬移的高昂成本,也避免了list因

weixin_33933118的博客 391

C/C++零基础到工程实践:从环境搭建到项目开发的完整学习路径

在计算机编程领域,理解程序如何与底层硬件交互是系统级开发的核心基础。C语言作为过程式编程的代表,通过指针和内存管理等机制,让开发者能够直接操作内存地址,深刻理解程序在内存中的布局和资源管理原理。这种对计算机系统底层运作机制的掌握,为构建高性能应用提供了技术基础。C++在此基础上引入了面向对象和泛型编程范式,通过类、对象、模板等特性支持更复杂的抽象建模,同时标准模板库(STL)提供了丰富的数据结构和算法组件,显著提升了开发效率。从环境配置、语法掌握到项目实践,学习C/C++不仅能建立扎实的编程思维,还能为游戏

weixin_33937913的博客 434
上一篇: 如何判断一个float/double是不是一个有效的值
下一篇: 快速高效的循环std::vector处理,以及std::vector::end函数
ShowLong
博客等级 码龄21年 61粉丝 67原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值