标签:释放内存 href 需要 cli delete tar sed oid 封装
前言
在讨论二维数组动态开辟与释放之前,先说说什么是二维数组静态开辟与释放。
形如这种就是静态开辟内存,事先画好了内存大小
#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++里面开辟二维数组,实际上没有上面那么麻烦。在看懂下面代码之前,需要向理解下面的思想
标签:释放内存 href 需要 cli delete tar sed oid 封装
原文地址:https://www.cnblogs.com/kelamoyujuzhen/p/9575324.html