二维数组动态开辟与释放

Posted kelamoyujuzhen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二维数组动态开辟与释放相关的知识,希望对你有一定的参考价值。

前言

在讨论二维数组动态开辟与释放之前,先说说什么是二维数组静态开辟与释放。

形如这种就是静态开辟内存,事先画好了内存大小

技术分享图片
#include<iostream>
using namespace std;

#define ROW 3
#define COL 4
int main()
{
    int ar[COL][ROW] = { 0 };
    return 0;
}
View Code

 技术分享图片

使用二级指针模拟二维数组

代码演示

技术分享图片
#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;
}
View Code

技术分享图片

 这段代码有个问题,内存泄漏。

泄露内存大小为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 }
View Code

代码封装一下,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 }
View Code

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 }
View Code

C++的常用做法

在C++里面开辟二维数组,实际上没有上面那么麻烦。在看懂下面代码之前,需要向理解下面的思想

 

 

以上是关于二维数组动态开辟与释放的主要内容,如果未能解决你的问题,请参考以下文章

动态内存管理

C语言篇 + 内存管理及柔性数组话题

动态内存管理

动态内存分配

创建动态二维数组

C语言进阶—— 动态内存开辟+柔性数组