数组内存申请和释放,指针数组和数组指针

一 数组指针的空间释放

int (*p)[3] = new int [4][3];
// ...
delete []p;    //---1
delete[](*p);  //---2


在释放这个二维数组时,应该使用1和2哪种方式呢?哪种对呢?

其实两种方法都是可以的,二维数组,p 和 *p 指向的位置相同的,都是指向第一个元素的地址是 &p[0][0]

对于C/C++如何检测内存泄露,就是简单的库调用,这里不赘述,详见下面代码和参考文献,不过注意,检测结果的信息输出是在调试的情况下查看输出窗口(output)的

#define _CRTDBG_MAP_ALLOC
#include 
#include 
 
#include 
 
void main()
{
    int (*p)[3] = new int [4][3];
 
    //delete []p;
    delete[](*p
 
    _CrtDumpMemoryLeaks();//调试运行到该步,输出检测信息
}


执行如代码所示,对于两种释放方式,都没有检测出内存泄露,说明这两种方式都是正确的。

二 动态二维数组的申请和释放

动态二维数组有两种形式,一种是指针数组,一种是数组指针

按照我自己的简单的理解:

指针数组,就是先申请一个指向数组的指针数组,然后再对每一个指针内部申请数组,一共有两次申请内存的过程

数组指针,就是一次性申请内存,直接获得一个二维数组的全貌

二者在内存的物理空间上是具有不同的表现形式的,如图所示,本节我们就简单讨论下。

数组内存申请和释放,指针数组和数组指针_第1张图片

#include 
 
void main()
{
    int * a = new int [3];
    printf("一维数组:\na:\t%d\n*a:\t%d\n&a[0]:\t%d\n\n"
        ,a,*a,&a[0]);
 
    // 使用指针数组
    int **ptr = new int*[4];
    for(int i = 0; i < 4; ++i)
    {
        *(ptr+i) = new int [3];
    }
    printf("指针数组一步步申请:\nptr:\t%d\n&ptr[0]:%d\n*ptr:\t%d\nptr[0]:\t%d\n&ptr[0][0]:%d\n\n"
        ,ptr,&ptr[0],*ptr,ptr[0],&ptr[0][0]);
 
    // 使用数组指针
    int (*p)[3] = new int [4][3];
    printf("数组指针:\np:\t%d\n&p[0]:\t%d\n*p:\t%d\np[0]:\t%d\n&p[0][0]:%d\n\n"
        ,p,&p[0],*p,p[0],&p[0][0]);
 
    // 释放内存
    for(int i = 0; i < 4; ++i)
    {
        delete [] ptr[i]; //注意不要漏掉方括号
    }
    delete []ptr;
 
    delete []p;
    delete []a;
}

一维数组:
a:      5284392
*a:     -842150451
&a[0]:  5284392

指针数组一步步申请:
ptr:    5284520
&ptr[0]:5284520
*ptr:   5284584
ptr[0]: 5284584
&ptr[0][0]:5284584

数组指针:
p:      5284808
&p[0]:  5284808
*p:     5284808
p[0]:   5284808
&p[0][0]:5284808

请按任意键继续. . .


对于方法一:ptr==&ptr[0],二者皆是指针数组的第一个元素的地址,而*ptr与ptr[0]则是指针所指向的整型数组空间的第一个元素的地址,即&ptr[0][0]。

对于方法二:我们可以看出,所有的变量都是一样的,说明该方法在物理空间上不存在多个新开辟的内存,只是一次性地申请了row*col大小的空间。即为什么使用数组指针动态申请二维数组在释放空间时的写法有多种。

在C++中,对于两种方法,在释放空间时,delete [] p表示释放指针p所指向的对象,务必要记得写“[]”,才能表示释放的是数组中的每一个元素,如果是对象,则会调用析构函数。

在C语言中的free(p)就没有那么多“麻烦”了,无论是单个内置类型还是数组,free()函数的参数只要求传入指针即可(不过C中没有类与对象的实例与析构了),为什么会这样?这就是malloc的机制问题,malloc不关心申请的空间是什么类型,只关心开辟的字节数,这样一来free只需知道指针便能正确地释放内存

说到这里,顺便小记一下new/delete和malloc/free的区别

  • new/delete是C++中的运算符,可以重载;malloc/free则是标准库函数
  • 如果是非内置对象类型,new/delete在执行时会相应地调用构造函数和析构函数; malloc/free则不会。
  • 使用方法上的区别,如上面划横线的部分分析。


你可能感兴趣的:(各种杂,内存释放,数组指针,指针数组,动态二维数组)