C++ vector插入操作insert解释

C++ vector插入操作insert解释

首先vector的底层实现也是普通数组。
vector的大小有两个维度一个是size一个是capicity,size就是我们平时用来遍历vector时候用的,例如:

for (int i = 0; i < vec.size(); i++) {

}

而capicity是vector底层数组(就是普通数组)的大小,capicity可不一定就是size。
当insert数据的时候,如果已经大于capicity,capicity会成倍扩容,但对外暴漏的size其实仅仅是+1。
那么既然vector底层实现是普通数组,怎么扩容的?
就是重新申请一个二倍于原数组大小的数组,然后把数据都拷贝过去,并释放原数组内存。
举一个例子,如图:
代码随想录:贪心算法:根据身高重建队列(续集)
原vector中的size和capicity相同都是3,初始化为1 2 3,此时要push_back一个元素4。
那么底层其实就要申请一个大小为6的普通数组,并且把原元素拷贝过去,释放原数组内存,注意图中底层数组的内存起始地址已经变了。
同时也注意此时capicity和size的变化,关键的地方我都标红了。
以上内容来自代码随想录贪心算法:根据身高重建队列(续集)

下面对插入元素后内存地址可能改变的说法进行验证,还是使用leetcode 406题的题解来验证,修改后代码如下:

class Solution {
public:
    static bool cmp(vector<int>& people1, vector<int>& people2) {
        if (people1[0] == people2[0]) return people1[1] < people2[1];
        return people1[0] > people2[0];
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), cmp);
        vector<vector<int>> res = {{0,0}}; //这里赋值初始化是为了便于下面访问首个元素,获取地址
        for (int i = 0;i < people.size();i++) {
            int h = people[i][1];
            cout<<"插入前首元素地址:"<<&(*res.begin())<<endl; // 这里获取插入元素前的首元素的地址;获取vector迭代器的地址方法:&(*it)
            res.insert(res.begin() + h, people[i]);
            cout<<"插入后首元素地址:"<<&(*res.begin())<<endl; // 这里获取插入元素后的首元素的地址
        }
        return vector<vector<int>>(res.begin(), res.end()-1);
    }
};
//输入如下:
/*
插入前首元素地址:0x6030000000a0
插入后首元素地址:0x6040000000d0
插入前首元素地址:0x6040000000d0
插入后首元素地址:0x6080000000a0
插入前首元素地址:0x6080000000a0
插入后首元素地址:0x6080000000a0
插入前首元素地址:0x6080000000a0
插入后首元素地址:0x610000000140
插入前首元素地址:0x610000000140
插入后首元素地址:0x610000000140
插入前首元素地址:0x610000000140
插入后首元素地址:0x610000000140
*/

可以看出有几次地址在插入后发生了变化,下面对这几次变化做一个说明:
从下图中可以模拟出res数组内存不断变化的过程,当插入元素超出capicity时,数组就会新开辟一块空间为原来2倍的内存,其首地址不同于原来的数组地址,然后再插入元素;而插入元素不超出capicity时,不扩容,内存空间也不变化。
res数组内存变化图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值