首页 > 其他分享 >不要轻易定义指向std::vector中的元素的指针

不要轻易定义指向std::vector中的元素的指针

时间:2023-11-26 15:13:55浏览次数:32  
标签:std 指向 int 元素 vector 指针

类应该是被封装的,类的用户通过接口使用类提供的功能,而不必关心类的内部如何实现。然而,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,指向,int,元素,vector,指针
From: https://www.cnblogs.com/pkuqcy/p/17857186.html

相关文章

  • 小白指针(七)--------新手入门
    我们之前讲了很多。但是指针的路还需要继续往下走,其实也快结束了,学习就是一种坚持的路,只有往前走才能学到更多,看到更多。(。・ω・。),今天的可能比前面的多,请耐心学习,谢谢在指针更新完之后我会将指针的内容,整理发一片这里是指针的快结束了,这里的一节结束还有最后有一片文章了,朋友们加油呀!一......
  • 深入指针
    一、指针概括1、指针定义 Def: 指针(pointer)也就是内存地址(指针==地址),指针变量是用来存放内存地址的变量,在同一CPU下,不同类型的指针变量所占用的存储单元长度是相同的,但所占空间大小由指针变量的类型所决定。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操......
  • 弄清using namespace std的作用
    ⭐C++标准为了和C区别开!为了正确地使用命名空间,规定头文件不使用后缀.h。例如当我们使用<iostream.h>时,相当于在C中调用库函数。使用usingnamespacestd例如1#include2#include3#include4usingnamespacestd;这样使用的话,就相当于std命名空间内所有的标识符都已声......
  • c语言中的指针用法
    1、指向函数的指针在C语言中,函数名实际上是一个指向函数的指针,所以你可以直接使用函数名add来初始化函数指针,而不需要使用&add。在这种情况下,add和&add是等价的。这是因为在C语言中,函数名是函数的入口地址的别名。当你使用函数名时,你实际上获取的是函数的入口地址。这就是为什么......
  • C++11 多线程(std::thread)实例
    C++11的std::thread在C中已经有一个叫做pthread的东西来进行多线程编程,但是并不好用(如果你认为句柄、回调式编程很实用,那请当我没说),所以c++11标准库中出现了一个叫作std::thread的东西。std::thread常用成员函数构造&析构函数举个栗子例一:thread的基本使用1//Compiler:......
  • std::thread方法join与detach
    1、std::joinstd::join是std::thread类的成员函数之一,用于等待线程的执行完成。#include<iostream>#include<utility>#include<thread>#include<chrono>#include<atomic>voidprocess(std::stringstr_info){for(inti=0;i<500;++i)......
  • 10_填充每个节点的下一个右侧节点指针
    填充每个节点的下一个右侧节点指针给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:structNode{intval;Node*left;Node*right;Node*next;}填充它的每个next指针,让这个指针指向其下一个右侧节点。如果找不到下一个......
  • surface pro4 鼠标指针闪烁、触摸屏不灵
    同事的平板长时间不用。出现:鼠标指标闪烁,触摸屏不灵的情况。尝试:一、更新系统问题依然出现二、调整各种设置总是依然出现三、百度到一篇可能是设备冲突禁用人机接口中的第一个“符合HID标准的触摸屏”总是解决。各文中提到的现象不完全一致,但类似。猜想可能是设备冲突引......
  • std::function 与 std::bind解决类成员函数作为回调函数的问题
    1、std::functionstd::function是一个模板类,其可对C++可调用的对象进行封装,比如,成员函数、静态函数等;它的基本作用是简化调用的复杂程度,归一化调用方式。std::function<int(int,int)>int_function:声明方式为<返回值类型(参数类型1,参数类型2,...)>,其可封装任何可调用的......
  • 【转载】Qt中的智能指针
    不用到处找了,附高质量博客链接Qt智能指针介绍:QSharedPointer、QWeakPointer、QScopedPointer、QPointer(附实例)-CSDN博客Qt智能指针信号槽连接问题_qtconnect智能指针_Jason~shen的博客-CSDN博客......