c语言二维数组和c++ 二维vector在内存中存储的区别

c语言二维数组

c语言数组的元素在内存中是连续存储的
所以会出现以下情况

int main()
{
	int arr[][3] = { {1,2,3},{4,5,6} };
	printf("%d %d\n", arr[0][2],arr[1][0]);
	printf("%d %d\n", arr[0][3], arr[1][0]);

	return 0;
}

在这里插入图片描述

arr[0][3]即arr[1][0]
因为下标运算符[]的运算方式是对指针进行加减然后进行访问
即:arr[1] 就是 *(arr+1)
arr[0][1] 就是 *(*(arr+0)+1)

所以arr[0][3],arr[1][0]两种形式算出来的值是一样的,都指向同一块地址(第四个元素)


c++二维vector

在vector中却不能执行相同的操作,out of range,超出范围
在这里插入图片描述

vector在vs2022 x86中所占大小为16
所有大小与元素个数无关 sizeof (vector)取决于vector类的具体实现,STL是个完全开放的东西,谁都可以来实现vector类
二维vector中,每个子vector内部的元素内存是连续存储的,而各个子vector内部元素的内存却不是连续存储的
因为vector是个类,类似动态数组,元素的内存是被分配到堆区的,但其类本身是存储在栈区

vs2022中vector类的内部有三个指针 start,finish,end_of_storage 和一个空间适配器
所以在32位平台上vector占16字节,64位占32字节

在这里插入图片描述

int main()
{
	vector<vector<int>> q = { {1,2,3},{3,4,6},{7},{8},{9} };
	vector<int> vec = { 1,2,3,4 };
	int arr[2][2] = { {1,2},{3,4} };
	cout << sizeof(q) << endl;

	cout << endl;

	cout << "q[0][0]: " << &q[0][0] << endl;//每个子vector类的内部元素地址是连续存储的
	cout << "q[0][1]: " << &q[0][1] << endl;
	cout << "q[0][2]: " << &q[0][2] << endl;
	cout << "q[1][0]: " << &q[1][0] << endl;
	cout << "q[1][1]: " << &q[1][1] << endl;
	cout << "q[1][2]: " << &q[1][2] << endl;
	cout << endl;

	cout << "q[0]: " << &q[0] << endl;//每个子vector类的地址是在主vector中连续存储
	cout << "q[1]: " << &q[1] << endl;
	cout << "q[2]: " << &q[2] << endl;
	cout << "q[3]: " << &q[3] << endl;
	cout << "q[4]: " << &q[4] << endl;
	cout << endl;

	cout << "q[0][0]: " << &q[0][0] << endl;//每个子vector间的内存不是连续存储的,要在子vector类内的指针实现访问
	cout << "q[1][0]: " << &q[1][0] << endl;
	cout << "q[2][0]: " << &q[2][0] << endl;
	cout << "q[3][0]: " << &q[3][0] << endl;
	cout << "q[4][0]: " << &q[4][0] << endl;

	return 0;
}

在这里插入图片描述
可以看见q[0]–q[4]之间都隔了16个字节,说明子vector的地址在主vector里面是连续存储的
而子vector类内的指针指向的元素的内存存储在别的地址,分开存储,类存在栈区,元素是动态分配的地址所以在堆区
这足以说明了为什么vector不需要显式定义行列,因为其本质上就是动态数组
同时,各个子vector所指向的元素内存不会冲突,而且不需要考虑扩容时内存需求超过主vector会不够用的问题,因为其元素内存都存在别处而不是主vector里

这就是为什么vector不能同上面c语言的数组一样访问元素内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值