在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前言 在讨论多维数组动态开辟与释放之前,先说说什么是二维数组静态开辟与释放。 形如这种就是静态开辟内存,事先画好了内存大小 #include<iostream> using namespace std; #define ROW 3 #define COL 4 int main() { int ar[COL][ROW] = { 0 }; return 0; }
使用二级指针模拟二维数组 代码演示 #include<iostream> #include<assert.h> using namespace std; #define ROW 3 #define COL 4 int main() { int **p=(int**)malloc(sizeof(int*)*ROW); assert(NULL != p); for (int i=0;i<ROW;++i) { p[i] = (int*)malloc(sizeof(int)*COL); assert(NULL!=p[i]); } for (int i = 0; i< ROW; ++i) { for (int j = 0; j < COL; ++j) { p[i][j] = i + j; } } for (int i = 0; i< ROW; ++i) { for (int j = 0; j < COL; ++j) { cout << p[i][j]<<" "; } cout << endl; } return 0; } 这段代码有个问题,内存泄漏。 泄露内存大小为4*3 + 4*4*3 = 60 Byte。我们知道,进程的用户空间内存中有一段内存是程序运行时需要的(堆、栈、共享内存区),栈内存由OS动态开辟回收,我们malloc的内存时是在堆中,需要我们手动释放,否则就会内存泄露。 free(p)这么释放内存可以吗? 不可以,这么仅仅是把3个int*释放了,后面int*指向的内存泄露。 正确释放内存,先释放int*指向的内存,在释放p指向的内存(即3个int*内存) 1 #include<iostream> 2 #include<assert.h> 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<ROW;++i) 12 { 13 p[i] = (int*)malloc(sizeof(int)*COL); 14 assert(NULL!=p[i]); 15 } 16 for (int i = 0; i< ROW; ++i) 17 { 18 for (int j = 0; j < COL; ++j) 19 { 20 p[i][j] = i + j; 21 } 22 } 23 for (int i = 0; i< ROW; ++i) 24 { 25 for (int j = 0; j < COL; ++j) 26 { 27 cout << p[i][j]<<" "; 28 } 29 cout << endl; 30 } 31 for (int i=0;i<ROW;++i) 32 { 33 free(p[i]); 34 } 35 free(p); 36 return 0; 37 } 代码封装一下,malloc版本 1 #include<iostream> 2 #include<assert.h> 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<row; ++i) 13 { 14 p[i] = (Type*)malloc(sizeof(Type)*col); 15 assert(NULL != p[i]); 16 } 17 return p; 18 } 19 20 void _Assign(Type **p, int row, int col) 21 { 22 for (int i = 0; i< row; ++i) 23 { 24 for (int j = 0; j < col; ++j) 25 { 26 p[i][j] = i + j; 27 } 28 } 29 } 30 31 void _Print(Type **p, int row, int col) 32 { 33 for (int i = 0; i< row; ++i) 34 { 35 for (int j = 0; j < col; ++j) 36 { 37 cout << p[i][j] << " "; 38 } 39 cout << endl; 40 } 41 } 42 43 void _Free(Type **p, int row) 44 { 45 for (int i = 0; i<row; ++i) 46 { 47 free(p[i]); 48 } 49 free(p); 50 } 51 int main() 52 { 53 Type **p = _Malloc(ROW,COL); 54 _Assign(p,ROW,COL); 55 _Print(p, ROW, COL); 56 _Free(p, ROW); 57 return 0; 58 } new版本 1 #include<iostream> 2 #include<assert.h> 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<row; ++i) 13 { 14 p[i] = new Type[col]; 15 assert(NULL != p[i]); 16 } 17 return p; 18 } 19 20 void _Assign(Type **p, int row, int col) 21 { 22 for (int i = 0; i< row; ++i) 23 { 24 for (int j = 0; j < col; ++j) 25 { 26 p[i][j] = i + j; 27 } 28 } 29 } 30 31 void _Print(Type **p, int row, int col) 32 { 33 for (int i = 0; i< row; ++i) 34 { 35 for (int j = 0; j < col; ++j) 36 { 37 cout << p[i][j] << " "; 38 } 39 cout << endl; 40 } 41 } 42 43 void _Delete(Type **p, int row) 44 { 45 for (int i = 0; i<row; ++i) 46 { 47 delete []p[i]; 48 } 49 delete []p; 50 } 51 int main() 52 { 53 Type **p = _New(ROW,COL); 54 _Assign(p,ROW,COL); 55 _Print(p, ROW, COL); 56 _Delete(p, ROW); 57 return 0; 58 } C++的常用做法 在C++里面开辟二维数组,实际上没有上面那么麻烦。在看懂下面代码之前,需要向理解下面的思想。 数组的首元数是谁,指向数组首元素的指针真么写? 对于一维数组,如下图,首元素就是整型。整型数组首元素的地址就是int*。所以一维数组接收地址就是一个整型指针int*。 对于二维数组,必然涉及到行和列,他的首元素就不再是其中单独一行的某一个元数,而是整体一行,首元素的地址就是(一维数组的地址)int**。所以二位数组接收地址就是int**,也就是说需要使用int**指向首元素,因为首元素是一维数组,数组是int*类型。 二维数组代码演示 1 #include<iostream> 2 #include<assert.h> 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 } 三维数组代码演示 1 #include<iostream> 2 #include<assert.h> 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 }
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论