C++多维数组

1.首先,一维数组是指针

int array[10];
int* array=new int[10];

两种表达一样吗?(第一种有分配内存吗?应该没有吧,毕竟没有new)
这仅仅是分配10个int大小(sizeof(int))的内存,没有任何值在里面,array也仅仅是一个指针,指向这段内存。

二维数组:

int a2d[10][10];//声明
int** array2d=new int*[10];

有趣的是第二行,也仍然仅仅是分配内存。
这里声明了array2d,它是指针,指向一个一维数组,而这个一维数组存储的不是int类型,而是int*类型,也就一维数组中分配了10个指针大小的内存。而且这个array2d也是指针,指向这个一维数组。

继续第二行:

int** array2d=new int*[10];
for (int i=0;i<10;i++)
{
array2d[i]=new int[10];
}

array2d[i]是一个指针,并且每个指针i都指向一个一维int数组,大小是10个sizeof(int)
因此是个二维数组,二维数组也就是一个pointer which point to one dimension array of pointers,而这个数组每个元素又指向一个数组。
可以想象为表格索引。

继续深入三维,可以想象成为立方体存储块。
类似二维数组,首先说明三维数组是一个指针,这个指针指向pointers which point to pointers which point to pointers. 这pointers里面的复数大小,取决于申请的空间大小。

int*** array3d=new int**[10];
for (int i=0;i<10;i++)
{
    array3d[i]=new int*[10];
    for (int j=0;j<10;j++)
    {
      array3d[i][j]=new int[10];
    }
}

其中,array3d,array3d[i],array3d[i][j]都是指针。array3d[][]是指向int数组的指针。而另外两个则都是指向pointer数组的指针。(这么说不一定严格准确,仅仅为了理解)这里面说的数组严格意义上对应的是内存空间。

int*** array3d=new int**[10];
for (int i=0;i<10;i++)
{
    array3d[i]=new int*[10];
    for (int j=0;j<10;j++)
    {
     int** ptr=array3d[i]//能理解这一个变化吗?为什么是int**
      ptr[j]=new int[10];
    }
}

回答注释中的问题,因为恰恰是array3d[i]是一个pointer which point to int*[10],而这10个单位内存空间也分别存储着一个pointer which point to int[].也就是array3d[i][j]=new int[10];

从底层往上面解释:每一个pointer 也就是 array3d[][]指向int[10],而一共有10个这样的指针(由array3d[i]指向这10个指针),因此可以指向1010个int内存空间。而10个这样的array3d[i]作为一个数组(内存块),由array3d指向,因此array3d也就指向1010*10个int内存。

所以说,可以想象成立方体,然后坐标系x,y,z范围都是1-10。
你不妨可以对应一下x,y,z都分别是array3d[][],array3d[],array3d这三个哪一个?然后其每一个刻度都是int还是pointer.

参考答案:
如果x是array3d[][],y是array3d[],z是array3d。那么x对应的刻度1-10是对应int,其他对于指针pointer.

2.回到二维,观察delete:

delete[][] array2d;//会报错
delete[] array2d;//语法正确,但会导致内存泄漏

第二个我们只是删除了10个指针也就是删除了10sizeof(int)的内存空间,但是并没有删除这10个指针所指向的1010个sizeof(int)内存空间,因此我们将找不到这个1010个sizeof(int)的内存空间了,因为这10个指针没了。–>内存泄漏(memory leak)
因此需要:

for (int i=0;i<10;i++)
{
array2d[i]=new int[10];
}
for (int i=0;i<10;i++)
{
delete[] array2d[i];
}
delete[] array2d;//还需要此步骤才能彻底删除

array2d并不拥有连续的一整个个100sizeof(int)的内存空间,而是拥有10 separate buffer of 10 sizeof(int)空间,是 10个单独的10sizefo(int)空间,而不是直接100个。
但是我们可以随意存储这1010sizefo(int)中。
但是这种存储方式会比较慢,因为需要iterate,我们需要先寻找10个pointers which point to 一维数组,然后再降维进入一维数组。
远不如直接存储在100*sizeof(int)个一维数组上面快。因为一维数组是一段连续的空间。
因此,我们可以这样写代码:

int** array2d=new int*[10];
for (int i=0;i<10;i++)
{
  array2d[i]=new int[10];
}
int* array2d=new int[10*10];
for (int i=0;i<10;i++)
{
   for (int j=0;j<10;j++)
   {
    array2d[i]=new int[j+i*10]; //将步长改为10
   }
}

cool!
我们可以借此存储所有的二维、三维数组,比如图片的pixel,立方体的voxel。
欢迎大佬指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值