数组的动态分配

来源:互联网 发布:源码说明文档模板下载 编辑:程序博客网 时间:2024/06/03 15:38

一、一维数组的动态分配

一维数组动态分配形式如下:

int n=2;int *a = new int[n];  //动态分配的数组a存放在内存中的堆中//使用完后要手动释放内存,否则会内存泄漏delete [] a;  //数组应该加上[]表明是个数组,虽然不加也不报错,但是有内存泄漏的风险a=0;  //将a赋值0,上面的删除虽然释放了内存占用的空间,但是变量a并没有消失,这里置零是为了避免a成为野指针

这里给出变量或对象的动态分配形式,进行对比:

int *pa = new int(2);   //存放在内存中的堆中cout << *pa << endl;//使用完后也要释放动态分配的内存delete pa;  //是变量或对象,无需加上[]pa = 0;  //也要将pa置零,理由和上面动态分配一维数组一样,避免pa成为野指针

如果一维数组作为函数形参,可以采用的形式如下:

#include <iostream>using namespace std;void show(int *a, int n){            //以指针的形式传入可以,数组长度作为另外的形参    for(int i = 0; i < n; i++){        cout << a[i] << " ";    }    cout << endl;}void show2(int a[], int n){          //一位数组其实就是指针,所以采用这种形式也可以,是等价的                                    //也要将数组长度作为另外形参传入,否则以show2(int a[n])形式传入的话,报错n未定义    for(int i = 0; i < n; i++){        cout << a[i] << " ";    }    cout << endl;}void test1(){    int n=2;    int *a = new int[2];    for(int i = 0; i < n; i++){        a[i] = 2;    }    show(a,n);    //show2(a,n);}void test2(){    int n = 2;    int a[n] = {2, 2};    //show(a,n);    show2(a,n);}int main(){    //test1();    test2();    return 0;}

上面程序中因为一位数组其实就是指针所以两种传入形参的方式都是对的。后面会看到二维数组的情况就不同了。

二、二维数组的动态分配

二维数组动态分配内存的形式如下:

int n = 2, m = 2;int **a == new int*[n];  //也是存放在堆上for(int i=0; i < n;i++){    a[i] = new int[m];}//使用完后也需要手动释放内存,否则会出现内存泄漏for(int i=0;i < n; i++){    delete [] a[i];    a[i]=0;     //避免野指针}delete [] a;a = 0;    //避免野指针

如果要将二维数组作为函数形参,可以采用的形式如下:

#include <iostream>using namespace std;void show(int **a, int n, int m){    for(int i = 0; i < n; i++){        for(int j = 0; j < m; j++){            cout << a[i][j] << " ";        }        cout << endl;    }}const int s = 2, t = 2;     void show2(int a[][t], int s){   //制定的列的长度必须是常量,否则编译报错,所以将 t 定义成了常量,而且因为这里要用到,所以定义成全局常量     for(int i = 0; i < s; i++){        for(int j = 0; j < t; j++){            cout << a[i][j] << " ";        }        cout << endl;    }}void show3(int a[s][t]){            //同理必须是常量,行长度其实不用指定,但是这样可以多传入一个形参,简化了    for(int i = 0; i < s; i++){        for(int j = 0; j < t; j++){            cout << a[i][j] << " ";        }        cout << endl;    }}void test1(){    //动态分配二维数组     int n = 2, m = 2;    int **a = new int*[n];    for(int i = 0; i < n; i++){        a[i] = new int[m];    }    //初始化二维数组     for(int i = 0; i < n; i++){        for(int j = 0; j < m; j++){            a[i][j] =  2;        }    }    show(a, n, m);   //正确的,可以正常编译运行    //show2(a,n);   //错误的,不能将 int **类型转换成 int (*)[2]类型    //show3(a);    //错误的,不能将 int **类型转换成 int (*)[2]类型    //手动释放二维数组的内存    for(int i = 0; i < n; i++){        delete [] a[i];        a[i] = 0;    }     delete [] a;    a = 0;}void test2(){    int a[s][t] = {2, 2, 2, 2};    //show(a,s,t);   //这是错误的,不能将int (*)[2]类型转换成int **类型     show2(a, s);  //正确的,可以正常编译运行    //show3(a);   //正确的,可以正常编译运行}int main(){    //test1();    test2();    return 0;}

由上面的程序可以看到,动态分配的二维数组作为函数形参时和一维数组不同,二维数组不是简单地int *指针,而是int ()[常量]类型,不能互转。使用定义int a[n][m]确实比较简单,但是造成在作为函数形参时很复杂,需要传入固定长度的列长度,没有传入二维数组指针方便,两种方式有利有弊,但更建议用动态分配二维数组的方式,这样在作为函数形参时,更加具有可拓展性。

1 0
原创粉丝点击