对于二维数组,我们知道可以用Type ArrayName[Row][Colume]的方式来定义,这是一种静态内存开辟的方式,程序在编译的时候就为该数组分配了空间,而且行和列大小也是指定的。这篇文章里我们来看看二维数组动态内存开辟,开辟空间的大小是运行时才知道,这样可以更实现功能是可以更灵活。
首先我们来看看如何在内存上分配以实现二维数组的存储。
假如我们要实现一个3行4列,元素是int类型的二维数组,为了能像静态分配方式一样,使用两个下标i,j分别对应行列的方式访问二维数组,我们要如下分配空间:
对于这样一个内存布局,当我们要访问第i行第j列的元素,我们就可以像静态分配方式一样,利用p_array2d[i][j];
下面我们就针对这种方式来实现:
(1)初始化:
1 #include <stdio.h> 2 #include <malloc.h> 3 #include <assert.h> 4 #define ROW 3 5 #define COLUME 4 6 7 void main() 8 { 9 int **p_array2d = NULL; 10 p_array2d = (int **)malloc(sizeof(int *) * ROW);//分配的空间是行数,每一个空间对应指向行空间的第一个元素 11 assert(p_array2d != NULL); 12 for (int i = 0; i < ROW; i++) 13 { 14 p_array2d[i] = (int *)malloc(sizeof(int) * COLUME);//为每一行分配空间,元素个数是列值 15 assert(p_array2d[i] != NULL); 16 } 17 }
(2)遍历赋值:
1 for (int i = 0; i < ROW; i++) 2 { 3 for (int j = 0; j < COLUME; j++) 4 { 5 p_array2d[i][j] = i + j; //可以像静态分配的方式访问,使用p_array2d[i][j] 6 } 7 }
(3)遍历打印:
1 for (int i = 0; i < ROW; i++) 2 { 3 for (int j = 0; j < COLUME; j++) 4 { 5 printf("%d ", p_array2d[i][j]); 6 } 7 printf(" "); 8 }
(4)释放空间:
1 for (int i = 0; i < ROW; i++)//先释放为每一行元素开辟的空间 2 { 3 free(p_array2d[i]); 4 p_array2d[i] = NULL; 5 } 6 free(p_array2d);//释放为保存行首元素地址开辟的空间 7 p_array2d = NULL;
最后我们将程序的功能模块化,不同的功能封装到函数中:
#include <stdio.h> #include <malloc.h> #include <assert.h> #define ROW 3 #define COLUME 4 typedef int Type; Type **_InitArray2d(int row, int colume) { Type **p_array2d = NULL; p_array2d = (Type **)malloc(sizeof(Type *) * row); assert(p_array2d != NULL); for (int i = 0; i < row; i++) { p_array2d[i] = (Type *)malloc(sizeof(Type) * colume); assert(p_array2d[i] != NULL); } return p_array2d; } void _AssignArray2d(Type **p_array2d, int row, int colume) { for (int i = 0; i < row; i++) { for (int j = 0; j < colume; j++) { p_array2d[i][j] = i + j; } } } void _PrintArray2d(Type **p_array2d, int row, int colume) { for (int i = 0; i < row; i++) { for (int j = 0; j < colume; j++) { printf("%d ", p_array2d[i][j]); } printf(" "); } } void _DestroyArray2d(Type **p_array2d, int row) { for (int i = 0; i < row; i++) { free(p_array2d[i]); p_array2d[i] = NULL; }
free(p_array2d); p_array2d = NULL; } void main() { Type **p_array2d = NULL; p_array2d = _InitArray2d(ROW, COLUME); _AssignArray2d(p_array2d, ROW, COLUME); _PrintArray2d(p_array2d, ROW, COLUME); _DestroyArray2d(p_array2d, ROW); }