对于二维数组,我们知道可以用Type ArrayName[Row][Colume]的方式来定义,这是一种静态内存开辟的方式,程序在编译的时候就为该数组分配了空间,而且行和列大小也是指定的。这篇文章里我们来看看二维数组动态内存开辟,开辟空间的大小是运行时才知道,这样可以更实现功能是可以更灵活。

首先我们来看看如何在内存上分配以实现二维数组的存储。

假如我们要实现一个3行4列,元素是int类型的二维数组,为了能像静态分配方式一样,使用两个下标i,j分别对应行列的方式访问二维数组,我们要如下分配空间:

对于这样一个内存布局,当我们要访问第i行第j列的元素,我们就可以像静态分配方式一样,利用p_array2d[i][j];

下面我们就针对这种方式来实现:

(1)初始化:

 #include <stdio.h>
#include <malloc.h>
#include <assert.h>
#define ROW 3
#define COLUME 4 void main()
{
int **p_array2d = NULL;
p_array2d = (int **)malloc(sizeof(int *) * ROW);//分配的空间是行数,每一个空间对应指向行空间的第一个元素
assert(p_array2d != NULL);
for (int i = ; i < ROW; i++)
{
p_array2d[i] = (int *)malloc(sizeof(int) * COLUME);//为每一行分配空间,元素个数是列值
assert(p_array2d[i] != NULL);
}
}

(2)遍历赋值:

     for (int i = ; i < ROW; i++)
{
for (int j = ; j < COLUME; j++)
{
p_array2d[i][j] = i + j; //可以像静态分配的方式访问,使用p_array2d[i][j]
}
}

(3)遍历打印:

     for (int i = ; i < ROW; i++)
{
for (int j = ; j < COLUME; j++)
{
printf("%d ", p_array2d[i][j]);
}
printf("\n");
}

(4)释放空间:

     for (int i = ; i < ROW; i++)//先释放为每一行元素开辟的空间
{
free(p_array2d[i]);
p_array2d[i] = NULL;
}
free(p_array2d);//释放为保存行首元素地址开辟的空间
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 = ; 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 = ; i < row; i++)
{
for (int j = ; j < colume; j++)
{
p_array2d[i][j] = i + j;
}
}
} void _PrintArray2d(Type **p_array2d, int row, int colume)
{
for (int i = ; i < row; i++)
{
for (int j = ; j < colume; j++)
{
printf("%d ", p_array2d[i][j]);
}
printf("\n");
}
} void _DestroyArray2d(Type **p_array2d, int row)
{
for (int i = ; 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);
}

C Program进阶-二维数组动态内存开辟的更多相关文章

  1. C++二维数组动态内存分配

    对于二维数组和二维指针的内存的分配 这里首选说一下一维指针和一维数组的内存分配情况. 一维: 数组:形如int  a[5];这里定义了一个一维数组a,并且数组的元素个数是5,这里的a是这五个元素的整体 ...

  2. c指针与数组,传参问题,指针数组与数组指针的区别,二维数组动态内存分配

    一 数组的结构:顺序存储,看谭浩强中的图,牢记 1.数组名指代一种数据结构:数组 现在可以解释为什么第1个程序第6行的输出为10的问题,根据结论1,数组名str的内涵为一种数据结构,即一个长度为10的 ...

  3. C++二维数组动态申请内存

    好久没用C++刷题了,今天早上刷了几条题,感觉很陌生了.怪我,大二下实在太颓废了,没啥作为. 今天更新个关于c++二维数组内存申请的问题,当初作为菜鸟初学指针的时候,还是在这方面有点搞不通的.今天用到 ...

  4. C/C++动态二维数组的内存分配和释放

    C语言: 1 //二维数组动态数组分配和释放 //数组指针的内存分配和释放 //方法一 char (*a)[N];//指向数组的指针 a = (char (*)[N])malloc(sizeof(ch ...

  5. C++基础:二维数组动态的申请内存和释放内存

    使用二维数组的时候,有时候事先并不知道数组的大小,因此就需要动态的申请内存.常见的申请内存的方法有两种:malloc/free 和 new/delete. 一.malloc/free (1)申请一维数 ...

  6. C Program基础-二维数组

    一维数组可以看作一行连续的数据,只有一个下标.C语言允许构造二维数组甚至多维数组,在实际问题中有时候常常需要用到二维数组(例如数学上的矩阵),二维数组有两个下标,以确定某个元素在数组中的位置. (一) ...

  7. C/C++二维数组分配内存

    //C++方式 double **Q=new double*[row];    //初始化Q矩阵 for(int i=0;i<row;++i) Q[i]=new double[POS_NUM]( ...

  8. JavaScript中给二维数组动态添加元素的质朴方法

    var myData = new Array(); for(var i=0;i<tableDatas.length;i++){ var arr=tableDatas[i]; ...... /// ...

  9. 【Java学习笔记之八】java二维数组及其多维数组的内存应用拓展延伸

    多维数组声明 数据类型[][] 数组名称; 数据类型[] 数组名称[]; 数据类型数组名称[][]; 以上三种语法在声明二维数组时的功能是等价的.同理,声明三维数组时需要三对中括号,中括号的位置可以在 ...

随机推荐

  1. WebAPI 实现前后端分离的示例

    转自:http://www.aspku.com/kaifa/net/298780.html 随着Web技术的发展,现在各种框架,前端的,后端的,数不胜数.全栈工程师的压力越来越大. 现在的前端的框架, ...

  2. mysql主从延迟复制

    需求描述 正常情况下我们是不会有刻意延迟从库的需求的,因为正常的线上业务自然是延迟越低越好.但是针对测试场景,业务上偶尔需要测试延迟场景下业务是否能正常运行. 解决方案 针对这种场景mysql有一个叫 ...

  3. [MYSQL][2]索引

    创建表时创建索引: 在已经存在的表上创建索引: 方法一 方法二 删除索引:

  4. 使用ContentType处理大量的外键关系

    问题分析 在之前的一个商城的项目中使用了mysql, 提到mysql就是外键, 多对多等等一系列的表关系 因为是一个商城的项目, 这里面有优惠券, 商品有很多的分类, 不同的商品又有不同的优惠券 其实 ...

  5. JavaScript6里出现了哪些新语法、新特征?

    ES5是2009年就出来的,目前来说在我写这篇文章的时候基本上ES6在浏览器上面还没有普及,不过Google浏览器是支持ES6语法的,谁让Google是美国生产的呢... ES6现在使用的地方其实还是 ...

  6. Scala的符号入门

    Spark是由Scala编写的.Spark作为一款十分易用高效的大数据框架使用越来越广泛,Scala也随之有更多的人去学习. 语言相通,相信有python.java基础的程序员学习Scala并没有太大 ...

  7. 『Python基础-14』匿名函数 `lambda`

    匿名函数和关键字lambda 匿名函数就是没有名称的函数,也就是不再使用def语句定义的函数 在Python中,如果要声匿名函数,则需要使用lambda关键字 使用lambda声明的匿名函数能接收任何 ...

  8. Leecode刷题之旅-C语言/python-344反转字符串

    /* * @lc app=leetcode.cn id=344 lang=c * * [344] 反转字符串 * * https://leetcode-cn.com/problems/reverse- ...

  9. Prim算法堆优化

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> ...

  10. 笔记-django-视图

    笔记-django-视图 1.      dispatch 1.1.    overview To design URLs for an app, you create a Python module ...