• array new 与 array deletedelete


    以前在看C++书和上C++课的时候可以看到

    delete[] pointer;
    

    的用法,而大多数对于这个用法没有具体的解释,多是看到:

    有一个delete运算符的特殊语法,可以释放动态分配的数组内存:

    delete[] p_numbers;
    

    方括号告诉编译器,指针指向了一个数组,而不是单个值。

    引文自:《C++程序设计:现代方法》,14.2 指针和数组

    也没有说明如果缺少[]会带来的后果,猜想是内存泄露,但是不明就里,于是给我来带了C++内存管理诡谲的印象。不过最近侯捷先生的讲解却很是清晰。

    下方所说Complex类为仅包含两个double类型成员,String仅含一个char类型指针。

    构造##

    首先说的是构造,以Complex类为例:

    Complex *c = new Complex(1,2);
    

    执行过程为:

    Complex *c;
    void* mem = operator new( sizeof(Complex) ); //内部调用malloc(n),分配内存
    c = static_cast<Complex*>(mem);              //类型转换
    c->Complex::Complex(1,2);                    //→Complex::Complex(c,1,2),构造函数
    

    那么在内存中执行的时候分配内存为:

    红色部分为操作系统分配之Cookie,蓝色部分为填充位,目的是为了让整个长度为16的倍数。灰色区域内数据仅在Debug模式下出现,绿色区域为对象所占长度。可计算,Debug模式下的Complex实例长度为:

    8[两个双精度浮点实数] + (32+4)[调试模式] + (4×2)[Cookie] → 52 + 12[填充] → 40H
    

    那么此时向操作系统取内存时Cookie末位置1,即Cookie为00000041,释放时末位置0。之所以保持16(10H)的倍数即如此。

    Release下的String类型长度则为:

    4[指针] + (4×2)[Cookie] → 12 + 4[填充] → 10H
    

    释放##

    执行

    String *s = new String(1,2);
    …
    delete s;
    

    delete s的时候会:

    String::~String(s);     //析构函数
    operator delete(s);     //释放内存,其内部调用free(s)
    

    即执行String类析构函数后释放内存,释放Cookie标记段。看起来似乎没什么问题。

    数组##

    看一下

    Complex *c = new Complex [3];
    

    String *s = new String [3];
    

    的内存结构,可以发现是这样的:

    在顶部多存储了一个数组长度。那么执行deletedelete[]有什么区别呢?是这样的:

    可以看到,对于内存而言,delete一定会将Cookie标记段给释放掉,如果是类似Complex的数组,那么使用deletedelete[]的效果是一致的,但是针对String这类含指针类型的数组,使用delete仅执行首次析构,也就是在这里出现了内存泄漏。


    最近怎么关心内存泄漏了?

    程序跑了一晚上泄漏了8G内存,不关心一下怎么得了。

  • 相关阅读:
    插入节点方法appendChild和insertBefore
    大河剧《独眼龙政宗》梵天丸喜多对话台词
    ie6绝对定位层元素消失
    strtok函数相关理解
    [创建型模式] Prototype
    用C实现旋转棒进度条指示器
    使用不规则数组(ragged array)和agetline()将整个文件读入内存
    [创建型模式] AbstractFactory
    xcode_4_and_ios_sdk_4.3__final相关下载地址
    [创建型模式] Singleton
  • 原文地址:https://www.cnblogs.com/johnwii/p/5042218.html
Copyright © 2020-2023  润新知