看到很多有写malloc的,但是并不是很懂,请问如何用malloc来申请一个二维数组的内存
1条回答 默认 最新
关注 一、概念定义
1、二级指针
指针变量也是一种变量,也会占用存储空间,也可以使用
&
获取它的地址。
如果一个指针指向另外一个指针,我们就称它为二级指针,或者指向指针的指针。用C语言描述如下:int x = 1; int *p1 = &x; int **p2 = &p1;
当然,还有三级指针,四级指针,几乎很少用到,这里不再累述。大概是这幅样子:
int ***p3 = &p2; int ****p4 = &p3;
2、解引用
在学习一级指针的时候,我们用过
*
进行解引用。一级指针经过一次解引用,变成普通变量。二级指针经过一次解引用,变成一级指针。int *p1 = *p2;
3、力扣中的二级指针
在 LeetCode 中,选择 C语言 进行求解时,往往出现如下的情况,这是什么意思呢?
int** func(int** matrix, int matrixSize, int* matrixColSize, int* returnSize, int** returnColumnSizes){ }
参数名 变量类型 实际含义 matrix
二级指针 传入的矩阵首地址 matrixSize
普通变量 传入的矩阵的行数 matrixColSize
一级指针 传入矩阵每行的列数(注意是每行,所以是数组) returnSize
一级指针 传出矩阵的行数,由于需要作为参数返回,所以用指针取地址 returnColumnSizes
二级指针 传出矩阵的每行的列数,由于需要作为数组参数返回,所以用二级指针
对于
returnColumnSizes
这个参数,补充几点:
1)它是一个 指向数组 的 指针,这里数组是行数组;
2)*returnColumnSizes
是实际的那个数组,并且数组的每个元素是(*returnColumnSizes)[i]
代表的是列数;
3)return
是个前缀,代表它的定位是 返回值,而不是 函数传参;4、内存申请模板
所谓模板,就是写完以后,每个题目都能套着用,今天我们就来提炼一个有关于二维数组的内存申请的模板。大致声明如下:
int **myMalloc(int r, int c, int* returnSize, int** returnColumnSizes);
其中,返回值代表申请的二维数组(为了方便理解,我们叫矩阵吧)的首地址。
r
和c
代表矩阵的行和列,returnSize
是需要返回给调用方的,实际的矩阵的行,我们会在函数内部将它赋值为r
,而returnColumnSizes
也是需要返回给调用方的,只不过需要返回的是一个数组。所以需要用二级指针(思考:为什么返回数组要用二级指针)。
这个函数就可以作为我们的模板函数的,我们接下来来实现一下它:int **myMalloc(int r, int c, int* returnSize, int** returnColumnSizes) { int i; int **ret = (int **)malloc( sizeof(int *) * r ); // (1) *returnColumnSizes = (int *)malloc( sizeof(int) * r ); // (2) *returnSize = r; // (3) for(i = 0; i < r; ++i) { ret[i] = (int *)malloc( sizeof(int) * c ); // (4) (*returnColumnSizes)[i] = c; // (5) } return ret; }
- $(1)$ 申请一个矩阵(二维数组)的内存,行数为
r
,首地址为ret
,二维数组的类型为int **
,二维数组中每个元素的类型为一级指针,即int *
,对应sizeof(int *)
这个表达式; - $(2)$ 为这个矩阵的列申请一个数组来记录它每一行的列数,所以这个列数组的长度应该是行数
r
,由于需要作为参数返回给调用方,所以这里调用了一次解引用; - $(3)$
*returnSize
是需要返回的矩阵的行数,调用者不知道这个功能返回的矩阵有多少行,需要实现者告诉他,同样调用一次解引用; - $(4)$ 申请矩阵每一行的内存空间,每一行的长度为
c
,即列数; - $(5)$ 每一行的列数长度需要作为返回值返回,所以需要先解引用再索引到行号,即给
(*returnColumnSizes)
进行赋值;
二、扩展阅读
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 2无用- $(1)$ 申请一个矩阵(二维数组)的内存,行数为
悬赏问题
- ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
- ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
- ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
- ¥15 帮我写一个c++工程
- ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
- ¥15 关于smbclient 库的使用
- ¥15 微信小程序协议怎么写
- ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
- ¥20 怎么用dlib库的算法识别小麦病虫害
- ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启