C语言两行代码实现10×10二维数组内存分配与释放的原理问询
拆解C语言动态二维数组的实现疑问
先看被推荐的代码:
int (*mapTerrain)[10] = (int (*)[10])malloc(sizeof(int[10][10])); free(mapTerrain);
下面逐个解答你的疑问:
疑问1:int (*mapTerrain)[10]的定义及强制类型转换
你之前以为应该是int *,这是把它和普通指针搞混啦。int (*mapTerrain)[10]是指向包含10个int元素的数组的指针,不是指向单个int的指针。
- 普通的
int*指针,每次+1只会移动一个int的字节数;而这个指向数组的指针,每次+1会直接跳过10个int的长度,刚好对应二维数组的一行。这样你就能像使用静态二维数组mapTerrain[i][j]一样直接访问元素,编译器会自动帮你计算偏移量。 - 至于强制类型转换
(int (*)[10]),是因为malloc返回的是void*类型,C语言需要明确告诉编译器这个指针指向的是什么类型,这样后续的指针运算和数组访问才会正确。
疑问2:为什么用sizeof(int[10][10])而非malloc(sizeof(int*10*10))
首先纠正一下,sizeof(int*10*10)这个写法是错误的,正确的写法应该是10 * 10 * sizeof(int)。不过用sizeof(int[10][10])有几个好处:
- 它更直观,直接表达“我要分配一个10×10的int二维数组的内存大小”,可读性更强。
sizeof可以接收数组类型作为参数,它会计算出该数组所占的总字节数,和10*10*sizeof(int)的结果是完全一样的。- 这种方式分配的是一块连续的内存块,而如果用
int**配合多次malloc的方式,内存是分散的,连续内存不仅缓存友好,管理起来也更简单。
疑问3:为何仅需一次free(mapTerrain)
因为这段代码里malloc只分配了一整块连续的内存,mapTerrain就是指向这块内存起始地址的指针,整个10×10的二维数组都挤在这一块里。
而如果是用int**的方式(先malloc一个指针数组,再为每个指针malloc一行内存),那才需要先free每行的内存,再free指针数组。但这里的实现是单块内存,所以一次free就能释放所有分配的空间,不需要额外操作。
内容的提问来源于stack exchange,提问作者Platon Makovsky
相关产品推荐
相关产品推荐

