类应该是被封装的,类的用户通过接口使用类提供的功能,而不必关心类的内部如何实现。然而,C++标准库容器 std::vector 的实现渗透到了接口中来。对于以下代码:

    const int pushNum = 10;
std::vector<int> v = { 1,2,3 };
int* p = &v[1];
std::cout << "*p = " << * p << std::endl;
std::cout << "v[1] = " << v[1] << std::endl;

for (int i = 0; i < pushNum; i++)
v.push_back(i);
std::cout << "---------------------" << std::endl;

std::cout << "*p = " << *p << std::endl;
std::cout << "v[1] = " << v[1] << std::endl;

我们初始化了一个有3个int元素的vector,定义了一个int 指针p,指向v[1] , 打印 *p 以及v[1] 的值。 然后向 v 中push_back() 了10 个元素,之后再次打印 *p 以及 v[1] 的值。在作者的环境中,程序的运行结果如下:

可以看到,在最初的v 中,打印出的*p 以及 v[1] 的值都是2, 这正是容器中下标为 1 的元素的值。 而push_back() 一些元素之后,v[1] 仍然是2,但是*p 的值却变了。指针p指向的就是v[1] ,为什么会这样呢?原因要追溯到标准库std::vector的实现。

std::vector 对象动态管理内存空间,一个std::vector 对象所分配的所有内存空间未必都构造了元素。可以使用其成员函数size() 返回其已构造的元素数量, 使用capacity() 返回其已分配的总容量,即,已分配的内存一共可以构造多少个元素。随着我们不断push_back(),size 会逐渐增加,直到capacity没有足够的空间能够容下下一个元素,这时,std::vector就会分配更多的内存。然而,std::vector 要求元素是连续存储的,如果此时连续的内存已经没有更多的空间了,std::vector会把所有元素搬到一块其他的,更大的内存空间,来容纳更多元素,并且其内部实现会保证其重载的下标访问运算符 [ ] 是有效的,然而std::vector 无法得知此时有一个指针p指向了容器内的元素,所以无法更新指针,而指针所指向的旧的内存现在是未知的。

那么std::vector 每次重新分配的时候会申请多大的空间作为capacity() ? 作者在自己的环境中做了一些实验,但并没有发现什么规律。

不要轻易定义指向std::vector中的元素的指针的更多相关文章

  1. vector中的元素删除

    删除vector中的元素,最容易的方法就是使用vector的erase()函数. vector vec;for ( vector::iterator iter = vec.begin(); iter! ...

  2. std::set 中内部元素有序条件删除的理解

    std::set 中内部元素有序条件删除的理解 1. std::set中的元素是有序排列的 注意:Set集合中的元素通过iterator的引用,但是不能修改. 元素排序: (1)元素中实现比较oper ...

  3. 关于Vector中的元素中含有指针成员的情况

    对于容器,当容器的各个元素为类类型,且该类类型中含有指针成员时: 如果类类型的析构函数中包含了对指针变量指向内存的释放操作,则在利用clear()函数删除容器所有元素时,会自动调用类的析构函数,自动实 ...

  4. (c++ std) 查找 vector 中的元素

    You can use std::find from <algorithm>: std::find(vector.begin(), vector.end(), item) != vecto ...

  5. 元素为指针的vector的使用说明

    该程序演示了vector中的元素为指针的时候的对对象的操作. /* 功能说明: 元素为指针的vector的使用说明 实现方式: 使用this成员来显示各个对象的地址. 限制条件或者存在的问题: 无 * ...

  6. C++之vector中元素删除

    今天在删除vector中的元素中遇到一个问题,这里记录下来以便以后查阅. 预备知识:用到了erase()函数,对于一个容器c来说,假设迭代器为p,那么执行: c.erase(p)之后就删除了容器c中p ...

  7. 【转】java.util.vector中的vector的详细用法

    [转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...

  8. java.util.vector中的vector的详细用法

    ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.util.*; /** * 演示Vector的使用.包括Vector的创 ...

  9. C++ std::vector 基本用法2

    #include <iostream> #include <vector> using namespace std; int main() { int ar[10] = { 1 ...

  10. 查漏补缺:Vector中去重

    对于STL去重,可以使用<algorithm>中提供的unique()函数. unique()函数用于去除相邻元素中的重复元素(所以去重前需要对vector进行排序),只留下一个.返回去重 ...

随机推荐

  1. LabVIEW图形化TensoRT工具包的安装下载分享

    前言 Hello,大家好,我是virobotics(仪酷智能)今天我们一起来看一下如何安装[LabVIEWTensoRT工具包]. 一.LabVIEW图形化TensoRT工具包简介 工具包特点: 图形 ...

  2. 深入理解 Flutter 图片加载原理

    前言 随着Flutter稳定版本逐步迭代更新,京东APP内部的Flutter业务也日益增多,Flutter开发为我们提供了高效的开发环境.优秀的跨平台适配.丰富的功能组件及动画.接近原生的交互体验,但 ...

  3. 两种方式,轻松实现ChatGPT联网

    两种方式效果: 方式一:浏览器搜索内嵌插件 方式二:官方聊天页内嵌插件 首先,要有一个谷歌浏览器,然后再安装一个叫ChatGPT for Google,直接在谷歌里搜一下就能找,也可以Chrome应用 ...

  4. CodeForces 1343E Weights Distributing

    题意 多组样例 给定\(n,m,a,b,c\),给定一个长度为\(m\)的数组\(p[]\),给定\(m\)条边,构成一个\(n\)个点\(m\)条边的无向图,\(Mike\)想要从\(a\)走到\( ...

  5. 树状数组复习 leetcode 307

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  6. 《Python魔法大冒险》009 魔法之语:字符串的奥秘

    随着小鱼和魔法师的深入,他们来到了一个被薄雾笼罩的湖泊.湖中央有一个小岛,岛上有一棵巨大的古树,树上挂满了闪闪发光的果实,每一个果实上都刻着一个字母或符号. 小鱼好奇地问:"这些是什么果实? ...

  7. ipa客户端安装

    ipa客户端安装 安装操作官网 非交互式安装IPa客户端 kinit admin ipa host-find ipa host-add ipa host-add --help ipa host-add ...

  8. Codeforces Round 882 div.2 A

    Smiling&Weeping ----总有人间一两风,填我十万八千梦 A. The Man who became a God time limit per test 1 second mem ...

  9. Solution -「CF 1073G」Yet Another LCP Problem

    Description Link. 给定字符串,正整数集合 \(A,B\),满足 \(\forall u\in A,v\in B,1\le u,v\le n\). 求 \(\sum_{i\in A}\ ...

  10. Ubuntu22.04 编译安装nginx

    1.下载nginx软件包 https://nginx.org/en/download.html 2.压缩包上传服务器并解压缩 tar xf nginx-1.22.1.tar.gz 3.进入解压目录,编 ...