C++冷知识之(一):二维向量的内存空间是不连续的

	std::vector<std::vector<double>> res(row, std::vector<double>(col));
	for (int i = 0; i < row*col; i++)
	{
		if (&res[i][0] == &res[0][0] + i)
		{
			std::cout << "True" << std::endl;
		}
		else { std::cout << "False" << std::endl; }
	}

用途:在调用指针时,二维向量数据并不连续,因此并不适合调用指针。

原理

#include 
#include 
void vector_2dim_space()
{
    int row = 5;
    vector<vector<int>> v(row, { 1,2,3 });
    for (int i = 0; i < row; i++)
    {
        string temp;
        stringstream ss;
        ss << "v[" << i << "]";
        ss >> temp;

        cout << temp << "地址:" << &v[i] << " ";
        for (int j = 0; j < 3; j++)
        {
            ss.clear();
            ss << "v[" << i << "]" << "[" << j << "]";
            ss >> temp;
            cout << temp << "地址:" << &v[i][j] << " ";
        }
        cout << endl;
    }
}

输出

v[0]地址:000001D7D8F64F10 v[0][0]地址:000001D7D8F70860 v[0][1]地址:000001D7D8F70864 v[0][2]地址:000001D7D8F70868
v[1]地址:000001D7D8F64F30 v[1][0]地址:000001D7D8F70DB0 v[1][1]地址:000001D7D8F70DB4 v[1][2]地址:000001D7D8F70DB8
v[2]地址:000001D7D8F64F50 v[2][0]地址:000001D7D8F705E0 v[2][1]地址:000001D7D8F705E4 v[2][2]地址:000001D7D8F705E8
v[3]地址:000001D7D8F64F70 v[3][0]地址:000001D7D8F70E00 v[3][1]地址:000001D7D8F70E04 v[3][2]地址:000001D7D8F70E08
v[4]地址:000001D7D8F64F90 v[4][0]地址:000001D7D8F70C70 v[4][1]地址:000001D7D8F70C74 v[4][2]地址:000001D7D8F70C78

每个vector内有四个成员变量,其中有三个迭代器(vector的迭代器其实就是指针)和一个空间配置器,我求了sizeof(vector)为16,x86下的(x64下的大小为32),大小是对应上了。

三个迭代器分别指向一块内存的三个位置,start指向目前使用空间的头,finish指向目前使用空间的尾,end_of_storage指向可用空间的尾部。

所以说结果中所示二维vector,刚好v[0]和v[1],v[1]和v[2]…的差距为32。也就是说每个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,在x64下,v[0]和v[1]间隔仍是32,但是v[1][0]和v[1][1]之间间隔却变成long的大小。vector类型的内部只有三个迭代器和一个空间配置器这四个成员变量。

你可能感兴趣的:(C++,c++)