二维vector的内存分配
新的改变
第一次写博客,难免比较粗糙。我也是一个非科班的,今年才开始学c++,问题很多,写的疏漏也很多,希望大家能指出来,但是温柔一点,毕竟我也是个小宝贝,嘿嘿。
之前的误区
之前一直以为二维vector的在内存中是各个一维vector拼接在一起的,今天才发现是错误的。
实际情况
在内存中,二维vector的每个子vector内部是连续的,但是子vector之间是非连续的。且vector[0]和vector[0][0]地址都是不同的。
我用vs2019进行测试的,我把一个二维数组插入了元素,然后输出每个元素的地址,结果如图
可以看到每个子vector是分配在不同的内存处,所以,二维vector初始的时候不需要指出行和列的范围,并且每一行的长度可以不同。每一行的数据增长也不会影响到别的行。因此在第i行前插入元素,不会导致像一维vector那样子,需要第i行后面的子vector元素都进行移动。当然,在某一行的某个元素前插入新数据,需要该行该元素后的元素进行移动。其实,vector本身就是一个new出来的一个动态数组,二维vector本质上跟创建二维数组是一样的。
结合源代码就好理解了很多。
每个vector内有四个成员变量,其中有三个迭代器(vector的迭代器其实就是指针)和一个空间配置器,我求了sizeof(vector)为16,x86下的,大小是对应上了。三个迭代器分别指向一块内存的三个位置,start指向目前使用空间的头,finish指向目前使用空间的尾,end_of_storage指向可用空间的尾部。所以说如图中所示二维vector,刚好v[0]和v[1],v[1]和v[2]…的差距为16。也就是说每个v[]里保存的是一个vector类型,v[i]指向的是一个vector类型,v[i][j]才是具体的元素,sizeof(int)的为4,刚好v[i][0]和v[i][1]…的间隔是4。每个子vector的元素保存在另外一块内存上,v[i]通过内部的迭代器找到v[i][j]。
对于二维vector的具体元素类型的改变,不会影响v[i]的大小,只会影响v[i][j]的内存大小。例如vector<vector>,在x86下,v[0]和v[1]间隔仍是16,但是v[1][0]和v[1][1]之间间隔却变成long的大小。vector类型的内部只有三个迭代器和一个空间配置器这四个成员变量。
后记
之前其实学过vector的一些知识,在学数据结构的时候,自己写过向量,但是当时觉得很简单,就是一个内部分配的动态数组,当时是内部声明了一个数组,也就导致了我今天理解二维vector存在很大偏差。果然啊,每一个小地方小细节都不可以忽略。配合源代码,其实很容易就能想到二维vector的内存分配情况。半瓶水晃荡,往后学习需要深入。