以二维数组为例,二维数组本质上是数组的数组,而三维数组是数组的数组的数组。
数组的数组 意思是数组的集合,处理数组的方式就是指针,指向数组在内存中的开头位置,而数组中存放每个数组的指针,于是组成了数组的数组

#include<iostream>
 
int main()
{
	int* array = new int[50];
	int** a2d = new int*[50];
}

array 指向一个开辟了 50 个 int 空间大小的内存,a2d 指向一个开辟了 50 个指针的内存块,每个指针可以再次分配内存块

#include<iostream>
 
int main()
{
	int** a2d = new int*[50];
	for(int i=0;i<50;i++){
		a2d[i] = new int[50];
	}
}

每个指针分配 50 个 int 类型的内存块,那么 a2d 可访问的内存变成了 50*50
多维数组最本质的核心还是一维数组,二维数组仅是使用一个一维数组存放了多个一维数组,更高维度则是不断嵌套一维数组

#include<iostream>
 
int main()
{
	int** a2d = new int*[50];
	for(int i=0;i<50;i++){
		a2d[i] = new int[50];
	}
	for(int i=0;i<50;i++){
		delete[] a2d[i];
	}
	delete[] a2d;
}

在堆上开辟的空间需要使用 delete 释放,而 delete 只能释放一维数组空间
而二维数组需要先释放最内层的一维数组,然后逐层释放,最后将最外层数组释放

通过对多维数组的了解后,会发现多维数组使用起来诸多不便,此外多维数组的分配和销毁容易产生内存碎片问题
a2d 无法保证整体内存块的连续性,在遍历数组时,特别是从一个一维数组切换到另一个一维数组时,会从一个内存块切换到另一个内存块,往往会导致 cache miss,从而降低运行效率
如果多维数组是连续分配,降低 cache miss 的发生,那么效率会大幅优化

#include<iostream>
 
int main()
{
	int* array = new int[50*50];
	for(int i=0;i<50;i++){
		for(int j=0;j<50;j++){
			array[i+j*50] = 2;
		}
	}
}

将多维数组展平,使用一维数组存储,会比多个一维数组存储的效率更高

TIP

尽量避免使用多维数组,尽可能将多维变成一维,可获得更快的运行效率