用C编写一个my2DAlloc函数,可分配二维数组。将malloc函数的调用次数降到最少,并确保可通过arr[i][j]访问该内存。
解法:
大家都知道,二维数组本质上就是数组的数组。既然可以用指针访问数组,就可以用双重指针来创建二维数组。
基本思路是先创建一个一维指针数组。然后,为每个数组索引,再新建一个一维数组。这样就能得到一个二维数组,可通过数组索引访问。
① 链式
下面是该做法的实现代码。
仔细观察上面的代码,注意我们是怎样让rowptr根据索引指向具体位置的。下图显示了内存是怎么分配的。
释放这些内存不能直接对rowptr调用free。我们要确保不仅释放第一次malloc调用分配的内存,还有释放后续每次malloc调用分配的内存。
②连续
我们还可以分配一大块连续的内存,这样就不必分配很多个内存块(每一行一块,外加一块内存,存放每一行的首地址)。举个例子,对于五行六列的二维数组,这种做法的效果如下图所示。
看到这样的二维数组似乎有点奇怪,注意,它与前一张图并没有什么不同。唯一区别是现在是一大块连续的内存,因此,此例中前五个要素指向同一块内存的其它位置。
下面是这种做法的具体实现。
注意,仔细观察第11~13行代码的具体实现。假设该二维数组有五行,每行六列,则array[0]会指向arra[5],array[1]指向array[11],依次类推。
随后,当我们真正调用array[1][3]时,计算机会查找array[1],这是个指针,指向内存的另一个地方,其实就是指向array[5]的指针。这个元素会被视为一个数组,然后取出它的第3个元素(索引从0开始)。
用这种方法构建数组只需要调用一次malloc,另外还有个好处,就是清除数组时也只需调用一次free,而不必专门写个函数释放其余的内存块。