weixin_41153503 2021-12-17 04:14 采纳率: 100%
浏览 45
已结题

c语言中的二维数组要怎么申请内存

看到很多有写malloc的,但是并不是很懂,请问如何用malloc来申请一个二维数组的内存

  • 写回答

1条回答 默认 最新

  • 英雄哪里出来 2021年博客之星Top1 2021-12-17 04:35
    关注

    一、概念定义

    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);
    

      其中,返回值代表申请的二维数组(为了方便理解,我们叫矩阵吧)的首地址。rc代表矩阵的行和列,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)进行赋值;

    二、扩展阅读

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月25日
  • 已采纳回答 12月17日
  • 创建了问题 12月17日

悬赏问题

  • ¥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交换机在配置过程中老是反复重启