前言
在讨论多维数组动态开辟与释放之前,先说说什么是二维数组静态开辟与释放。
形如这种就是静态开辟内存,事先画好了内存大小
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#includeusing namespace std;#define ROW 3#define COL 4int main(){ int ar[COL][ROW] = { 0 }; return 0;}
使用二级指针模拟二维数组
代码演示
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#include#include using namespace std;#define ROW 3#define COL 4int main(){ int **p=(int**)malloc(sizeof(int*)*ROW); assert(NULL != p); for (int i=0;i
这段代码有个问题,内存泄漏。
泄露内存大小为4*3 + 4*4*3 = 60 Byte。我们知道,进程的用户空间内存中有一段内存是程序运行时需要的(),栈内存由OS动态开辟回收,我们malloc的内存时是在堆中,需要我们手动释放,否则就会内存泄露。
free(p)这么释放内存可以吗?
不可以,这么仅仅是把3个int*释放了,后面int*指向的内存泄露。
正确释放内存,先释放int*指向的内存,在释放p指向的内存(即3个int*内存)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include2 #include 3 using namespace std; 4 5 #define ROW 3 6 #define COL 4 7 int main() 8 { 9 int **p=(int**)malloc(sizeof(int*)*ROW);10 assert(NULL != p);11 for (int i=0;i
代码封装一下,malloc版本
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include2 #include 3 using namespace std; 4 #define Type int 5 #define ROW 3 6 #define COL 4 7 8 Type** _Malloc(int row,int col) 9 {10 Type **p = (Type**)malloc(sizeof(Type*)*row);11 assert(NULL != p);12 for (int i = 0; i
new版本
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include2 #include 3 using namespace std; 4 #define Type int 5 #define ROW 3 6 #define COL 4 7 8 Type** _New(int row,int col) 9 {10 Type **p = new Type*[row];11 assert(NULL != p); //C++一般不用断言,而是使用异常机制12 for (int i = 0; i
C++的常用做法
在C++里面开辟二维数组,实际上没有上面那么麻烦。在看懂下面代码之前,需要向理解下面的思想。
数组的首元数是谁,指向数组首元素的指针真么写?
对于一维数组,如下图,首元素就是整型。整型数组首元素的地址就是int*。所以一维数组接收地址就是一个整型指针int*。
对于二维数组,必然涉及到行和列,他的首元素就不再是其中单独一行的某一个元数,而是整体一行,首元素的地址就是(一维数组的地址)int**。所以二位数组接收地址就是int**,也就是说需要使用int**指向首元素,因为首元素是一维数组,数组是int*类型。
二维数组代码演示
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include2 #include 3 using namespace std; 4 #define Type int 5 #define ROW 3 6 #define COL 4 7 8 //定义数组指针类型 9 typedef Type(*Ar)[COL];10 Ar _New()11 {12 Ar p= new Type[ROW][COL];13 return p;14 }15 16 void _Assign(Ar p, int row, int col)17 {18 for (int i = 0; i< row; ++i)19 {20 for (int j = 0; j < col; ++j)21 {22 p[i][j] = i + j;23 }24 }25 }26 27 void _Print(Ar p, int row, int col)28 {29 for (int i = 0; i< row; ++i)30 {31 for (int j = 0; j < col; ++j)32 {33 cout << p[i][j] << " ";34 }35 cout << endl;36 }37 }38 39 void _Delete(Ar p)40 {41 delete []p;42 }43 int main()44 {45 Ar p = _New();46 _Assign(p,ROW,COL);47 _Print(p, ROW, COL);48 _Delete(p);49 return 0;50 }
三维数组代码演示
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include2 #include 3 using namespace std; 4 #define Type int 5 #define ROW 3 6 #define COL 4 7 #define Z 5 8 9 //定义数组指针类型10 typedef Type(*Ar)[ROW][COL];11 Ar _New()12 {13 Ar p = new Type[Z][ROW][COL];14 return p;15 }16 17 void _Assign(Ar p, int row, int col, int z)18 {19 static int count = 0;20 for (int i = 0; i < row; ++i)21 {22 for (int j = 0; j < col; ++j)23 {24 for (int k = 0; k < z; ++k)25 {26 p[i][j][k] = ++count;27 cout.width(5);28 cout.flags(ios::left);29 cout << p[i][j][k] << " ";30 }31 cout << endl;32 }33 cout << endl;34 }35 }36 37 void _Print(Ar p, int row, int col, int z)38 {39 for (int k = 0; k < z; ++k)40 {41 for (int i = 0; i < row; ++i)42 {43 for (int j = 0; j < col; ++j)44 {45 cout.width(5);46 cout.flags(ios::left);47 cout << p[i][j][k] << " ";48 }49 cout << endl;50 }51 cout << endl;52 }53 }54 55 void _Delete(Ar p)56 {57 delete[]p;58 }59 int main()60 {61 Ar p = _New();62 _Assign(p, ROW, COL, Z);63 _Print(p, ROW, COL, Z);64 _Delete(p);65 return 0;66 }