吃过好几次二维数组动态申请的亏,现在总结一下。
什么时候需要动态申请内存呢?
- 当输入的数组大小不能事先确定;
- 同时你还想优化内存的使用,而不是简单的定义一个大数组时(例如:int a[1000000])
二维数组的动态申请
一维数组的动态申请这里不再赘述,相信大家经常能遇到也很熟悉,我们主要关心不常用的二维数组动态申请。
先上代码:
scanf("%d %d",&row,&column);
//二维数组的动态申请
int **numbers = (int **)malloc(row*sizeof(int *));//(1)
for(i = 0; i < row; i++)
numbers[i] = (int *)malloc(column * sizeof(int));//(2)
上面代码申请了一个row行、column列的二维数组 ,其中:
- 语句(1)表明二重指针指向的位置后面,有row*sizeof(int *) 这么大的空间;(二重指针说白了就是指针数组,它里面存放着很多一重指针)
- 语句(2)表明每个一重指针后面,有column * sizeof(int) 这么大的空间。(确定指针数组中,一重指针指向的内存块大小)
- 例如row = 3, column = 4,语句(1)即是申请了能盛3个int*指针这么大的空间(如下图蓝色),语句(2)即是对每个一重int*指针都申请了4个int大小的空间(如下图红色)
二重指针一般用的场合:
(1)二重指针指向一重指针的地址。
(2)二重指针指向指针数组的地址。
(3)实践中二重指针用得比较少,大多数都是和指针数组一起用的。
(4)实际编程时有时在函数传参时,为了通过函数内部改变外部的指针变量,通常用二重指针。
转自小米Sir的博客
最后,不要忘记将动态申请的堆内存释放掉,代码如下:
for(i = 0; i < row; i++)
free(numbers[i]); //逐个释放一维数组
free(numbers); //释放二维数组
小Tips
- 使用动态申请(**numbers)后的numbers,可以作为第一个参数传入下面的函数
void PrintMatrixClockWisely(int **numbers, int column, int row);
- 作为对比,使用静态申请(int numbers[Max][Max];)后的numbers,可以作为第一个参数传入下面的函数
void PrintMatrixClockWisely(int numbers[][Max], int column, int row);
这两种方式是很不同的,需要仔细体会,详细代码可以参考我的github,欢迎交流指正。