类应该是被封装的,类的用户通过接口使用类提供的功能,而不必关心类的内部如何实现。然而,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. Excel中的RIGHT函数

    问题:从数据库中导出35800个用户code(属于179家单位,每个单位200个用户),用户code共16位,前14位带有用户属性(如:角色.单位.部门等),后四位为每个单位用户的递增自然数.想要对全 ...

  2. 使用 KubeBlocks 为 K8s 提供稳如老狗的数据库服务

    原文链接:https://forum.laf.run/d/994 大家好!今天这篇文章主要向大家介绍 Sealos 的数据库服务.在 Sealos 上数据库后端服务由 KubeBlocks 提供,为用 ...

  3. 如何用PHP写接口

    当用PHP编写API接口时,可以使用PHP中的框架(如Laravel.Symfony.CodeIgniter等)来简化开发过程.接下来,以使用Laravel框架为例,提供一个简单的示例代码: 首先,确 ...

  4. 如何使用Python进行投资收益和风险分析

    如何投资是现代企业.个人投资者所面临的实际问题,投资的目标是收益尽可能大,但是投资往往伴随着风险,如果在保证收益最大化的情况下,风险最小:或是风险相同的情况下,如何实现收益的最大化:通过本实训,可以使 ...

  5. Ionic 整合 pixi.js

    最近做了个app,上线google play不大顺利,说是有假冒行为,然后改了下icon和名字以及描述,但是没啥信息去上,于是暂时放下搞点别的. 因为近期看到个比较有趣的绘图创意, 于是想通过ioni ...

  6. 局域网内文件分享的简单方式:python - http.server

    在局域网条件下,利用Python自带的HTTP服务功能提供文件共享服务是相对比较简单便捷的方式之一. 一.现实需求及前提条件 1. 文件的服务端(文件分享者)与接收端(文件接收者)在一个局域网,接收端 ...

  7. Solution Set -「CSP-S 2020」

    Problem. 1 - Junior Julian 模拟模拟模拟摸死 CTR 的母. 考场代码: #include<cstdio> namespace solveIt { void re ...

  8. Navicat连接MySQL,出现2059 - authentication plugin 'caching_sha2_password'的解决方法

    cmd(管理员)登录mysql执行如下 ALTER USER 'YOURUSERNAME'@'localhost' IDENTIFIED WITH mysql_native_password BY ' ...

  9. daffodil

    import java.util.ArrayList; public class Daffodil { /** * 打印出100-999之间所有的"水仙花数",所谓"水仙 ...

  10. 校招零Offer要不要先找实习?

    国庆前后被问到最多的问题是:"磊哥,我现在还是 0 Offer,要不要先去找个实习?",给大家看看部分截图. 同学 A: 同学 B: 同学 C: 其他还有一些截图,我这里就不一一贴 ...