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,每当它在堆栈上扩展/重新分配时会发生什么? 的相关文章

随机推荐

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