c++ Vector,每当它在堆栈上扩展/重新分配时会发生什么?

2024-03-21

我是 C++ 新手,我在我的项目中使用向量类。我发现它非常有用,因为我可以拥有一个在必要时自动重新分配的数组(即,如果我想推回一个项目并且向量已达到其最大容量,它会重新分配自身,向操作系统请求更多内存空间),所以访问向量的元素非常快(它不像列表,要到达“第 n”个元素,我必须遍历“n”个第一个元素)。

I found 这个问题 https://stackoverflow.com/questions/8036474/allocating-vectors-memory-on-heap-or-stack非常有用,因为他们的答案完美地解释了如何“内存分配器”当我想将向量存储在堆/堆栈上时有效:

[1] vector<Type> vect;
[2] vector<Type> *vect = new vector<Type>;
[3] vector<Type*> vect;

然而,有一个疑问困扰了我一段时间,我找不到答案: 每当我构造一个向量并开始推动时a lot的项目,它会达到向量已满的时刻,因此要继续增长,需要重新分配,将自身复制到新位置,然后继续 Push_back 项目(显然,这种重新分配隐藏在类的实现中,所以是完全透明 to me)

好吧,如果我在堆上创建了向量 [2],我可以毫不费力地想象可能会发生什么:类向量调用 malloc,获取新空间,然后将自身复制到新内存中,最后调用 free 删除旧内存。

然而,面纱掩盖了当我在堆栈上构造一个向量[1]:当向量必须重新分配时会发生什么? AFAIK,每当在 C/C++ 上输入一个新函数时,计算机都会查看变量的声明,然后expand堆栈以获得放置这些变量所需的空间,但是当函数已经运行时,您无法在堆栈上分配更多空间。类向量是如何解决这个问题的呢?


你写了

[...]将自身复制到新位置[...]

这不是向量的工作方式。矢量数据被复制到新位置,而不是矢量本身。

我的回答应该能让您了解向量是如何设计的。

常见的 std::vector 布局*

注:std::allocator实际上很可能是一个空类并且std::vector可能不包含此类的实例。对于任意分配器来说,情况可能并非如此。

在大多数实现中,它由三个指针组成,其中

  • begin指向堆上向量的数据内存的开头(如果不是则始终在堆上)nullptr)
  • end指向矢量数据最后一个元素之后的一个内存位置 ->size() == end-begin
  • capacity向量内存最后一个元素之后的内存位置上的点 ->capacity() == capacity-begin

堆栈上的向量

我们声明一个类型的变量std::vector<T,A> where T是任何类型并且A是一个分配器类型T (i.e. std::allocator<T>).

std::vector<T, A> vect1;

这在记忆中是什么样子的呢?

正如我们所看到的:堆上没有任何反应,但变量占用了堆栈上所有成员所需的内存。 它就在那里,并且会一直留在那里,直到vect1超出范围,因为vect1只是一个像任何其他类型的对象一样的对象double, int管他呢。无论它在堆上处理多少内存,它都会位于其堆栈位置并等待被销毁。

的指针vect1不要指向任何地方,因为向量是空的。

堆上的向量

现在我们需要一个指向向量的指针,并使用一些动态堆分配来创建向量。

std::vector<T, A> * vp = new std::vector<T, A>;

我们再看一下内存。

我们的 vp 变量在堆栈上,我们的向量现在在堆上。同样,向量本身不会在堆上移动,因为它的大小是恒定的。仅指针 (begin, end, capacity如果发生重新分配,则 ) 将移动到内存中的数据位置。让我们看一下。

将元素推入向量

现在我们可以开始将元素推入向量。让我们看看vect1.

T a;
vect1.push_back(a);

变量vect1仍然是原来的位置,但堆上的内存被分配来包含 的一个元素T.

如果我们再添加一个元素会发生什么?

vect1.push_back(a);
  • 堆上为数据元素分配的空间是不够的(因为它只有一个内存位置)。
  • 将为两个元素分配一个新的内存块
  • 第一个元素将被复制/移动到新存储。
  • 旧内存将被释放。

我们看到:新的内存位置不同了。

为了获得更多见解,让我们看看销毁最后一个元素时的情况。

vect1.pop_back();

分配的内存不会改变,但最后一个元素的析构函数将被调用,并且结束指针向下移动一个位置。

如你看到的:capacity() == capacity-begin == 2 while size() == end-begin == 1

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++ Vector,每当它在堆栈上扩展/重新分配时会发生什么? 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur

随机推荐

  • 如何在 Swift 中查找列表项的索引?

    我正在尝试寻找一个item index通过搜索list 有人知道该怎么做吗 我看到有list StartIndex and list EndIndex但我想要类似 python 的东西list index text 由于 swift 在某些
  • Spring Data cassandra 存储库上的插入和保存性能缓慢

    我正在尝试使用 spring 将 1500 条记录插入 cassandra 中 我有一个 POJO 列表 其中包含这 1500 条记录 当我调用 saveAll 或插入此数据时 需要 30 秒才能完成此操作 有人可以建议一种方法让我更快地完
  • start() 已经被调用。第二次调用将被忽略。

    在调用 start 后 在组件 StandardEngine Catalina StandardHost localhost StandardContext Account 上调用 start 方法 第二次调用将被忽略 请帮助我解决这些错误
  • 为什么 pandas df.loc + lambda 不起作用?

    I have created pandas frame from csv file And I want to select rows use lambda But it does not work I use this pandas ma
  • 无法运行程序“...”错误=2,没有这样的文件或目录(java)

    我正在尝试制作一个 java 程序来在我的 macbook 上建立 SSH 连接 它提示我输入用户名 然后是 IP 地址 然后应该执行 ssh username ip 下面是我的代码 import java io BufferedReade
  • 使用 Selenium 时如何选择要启用的 Chrome 扩展程序 [重复]

    这个问题在这里已经有答案了 我正在使用 Selenium Web 驱动程序使用 Chrome 作为浏览器来开发自动化测试 我为此使用Python 我的 Chrome 浏览器上有一个扩展 我希望在 Selenium 打开 Chrome 时启用
  • 如何实现推荐引擎?

    请耐心等待我的写作 因为我的英语不熟练 作为一名程序员 我想了解在推荐系统或相关系统下实现的算法或机器学习智能 例如 最明显的例子来自亚马逊 他们有一个非常好的推荐系统 他们会知道 如果你愿意this 你可能还喜欢that 或者其他类似的东
  • 将 DB 变量中的字节值加载到 16 位寄存器中(符号或零扩展字节)

    我正在使用 MASM 编译器和 DOSBOX 我想将变量的值保存到寄存器中 我想保存num1值转化为cx登记 我怎样才能做到这一点 MODEL SMALL STACK 50H DATA num1 db 5 NL DB 0DH 0AH msg
  • 为什么我们需要 Android 中的服务?音乐播放也可以通过后台线程来完成

    我在一次采访中被问到这个问题 我不确定这是否是问这个问题的正确论坛 因为它不涉及任何代码 而是对 android 概念的理解 问题是 当一切都可以通过 Android 中的后台线程完成时 为什么我们还需要服务 Service运行在主线程中
  • h:commandlink 中的 target="_blank" 未在浏览器的新选项卡中打开页面

    当 h commandLink 与 target blank 一起使用时 我的 h commandLink 正在同一页面 窗口上打开 预览 pdf 文档 我希望它在浏览器的新选项卡中打开 错误可能出在哪里 Preview xhtml代码
  • 将数组的 var_dump 转换回数组变量

    直到今天我才真正考虑过这个问题 但在网上搜索后我并没有真正找到任何东西 也许我在搜索中的措辞不正确 给定一个数组 多维或非多维 data array this gt array is gt the challenge gt array fo
  • 从 JavaScript 更改 href 值

    我在 JsFiddle 中有这个例子 http jsfiddle net PtNfD 114 http jsfiddle net PtNfD 114 a href http www yahoo com target blank Yahoo
  • 非英语文本的情感分析

    我想分析用德语写的文本的情感 我找到了很多关于如何用英语做到这一点的教程 但我没有找到关于如何将其应用到不同语言的教程 我有一个想法使用TextBlobPython 库首先将句子翻译成英语 然后进行情感分析 但我不确定这是否是解决此任务的最
  • 简而言之,关于 Func<> 可以说些什么

    我一直看到功能一段时间以来 我已经设法避免它 暂时 但现在看来 我是无法永远躲开了 例如 我尝试了 Dynamic Linq 但几乎所有内容都是根据 Func 进行的 我已经尝试过我的一本书 C 2008 Deitel Deitel 以及
  • WSH(wscript)是否可以与nodejs结合

    作为 QA 我使用 WSH 脚本在 IE 中进行自动上传 部署和一些 Web 测试 使用 JavaScript 的 WSH wscript 可以打开 IE 窗口 激活它并访问 DOM 模型来执行某些操作或验证某些预期结果 它是一种 Sele
  • 如何使多维数组变得唯一? [复制]

    这个问题在这里已经有答案了 我有一个多维数组设置 如下所示 array 0 gt array name gt Foo slug gt Bar 1 gt array name gt Foo slug gt Bar 2 gt array nam
  • Python 中模拟退火的基础知识 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我必须使用模拟退火来解决某个优化问题 为了 感受 该技术 我编写了一个小的 Python 代码并尝试运行它 然而 它似乎并没有给出令人满意
  • Android 运行时布局教程

    有谁知道如何在 android 运行时执行活动布局或有一个很好的参考 这是我的活动的代码 我确信我只是忽略了在这里做一些事情 package com isi sa import android app Activity import and
  • HTTP 是否重定向到 HTTPS 密码风险捕获?

    我在 NGINX 中设置了 http https 重定向配置 server listen 80 server name localhost return 301 https server name request uri 我的问题是 从用户
  • c++ Vector,每当它在堆栈上扩展/重新分配时会发生什么?

    我是 C 新手 我在我的项目中使用向量类 我发现它非常有用 因为我可以拥有一个在必要时自动重新分配的数组 即 如果我想推回一个项目并且向量已达到其最大容量 它会重新分配自身 向操作系统请求更多内存空间 所以访问向量的元素非常快 它不像列表