乐趣区

关于c++:C内存管理2array-new-arraydelete

资源透露危险剖析

  • 示例一:

    // 1. 唤起 三次构造函数
    // 2. 无奈藉由参数进行初始化,因而 Complex 须要有默认构造函数
    Complex *pca = new Complex[3];
    ...
    ...
    // 3. 唤起三次析构函数
    delete[] pca;

  • 示例二:

    // 1. 唤起 三次构造函数
    // 2. 无奈藉由参数进行初始化,因而 string 须要有默认构造函数
    string *psa = new string[3];
    ...
    ...
    // 3. 唤起一次析构函数
    delete psa;

  • 问:没对数组外面的每个对象调用析构函数(示例二),会有什么影响呢?

    • 对 class without pointer 可能没有影响(不会有资源泄露)
    • 对 class with pointer 通常有影响(会有资源泄露)
  • 阐明:

    • 示例一中,当 delete pca; pca 指向的全副内存空间将会被平安开释
    • 示例二中,当 delete psa; psa 指向的全副内存空间将会被平安开释,但因为 string 实现中蕴含指针指向一段堆空间中申请的内存空间以存储字符串,而数组元素数量的析构函数未被全副对应调用,导致字符串空间未被开释,因而会造成资源泄露
  • 总结

    • new, delete ; new [], delete [] 须要配对应用

数组元素的结构与析构程序

#include <iostream>

using namespace std;

class A
{
public:
    int id;

    A() : id(0) {cout << "default ctor.this=" << this << "id=" << id << endl;}

    A(int i) : id(i) {cout << "default ctor.this=" << this << "id=" << id << endl;}

    ~A() {cout << "dtor.this=" << this << "id=" << id << endl;}
};

constexpr size_t size = 3;

int main()
{
    // A 必须有默认构造函数
    // 默认结构函数调用三次,[0] 先于 [1] 先于 [2]
    A *buf = new A[size];

    A* tmp = buf;

    cout << "buf=" << buf << "tmp=" << tmp << endl;

    for (size_t i=0; i < size; ++i) {
        // placement new:在指定的地址结构对象
        new (tmp++)A(i);  
    }

    cout << "buf=" << buf << "tmp=" << tmp << endl;

    // 析构函数三次被调用(秩序逆反,[2] 先于 [1] 先于 [0])delete[] buf;

    return 0;
}
  • 总结

    • 数组中元素的结构程序与析构程序相同

在内存块中的数组大小

(array size, in memory block)

int *pi = new int[10];// from heap but not stack 
cout << sizeof(pi);    // 4
delete pi;
int ia[10];            // from stack but not heap
cout << sizeof(ia);    // 40
  • vc6 中的内存布局(后续将具体解说)
class Demo {
public:
    int a;
    omt 
};

==> (32 + 4) + 4 + 36 + (4 * 2) = 84 
==> 84 + 12 = 96 = 60H
==> 60H + 1H = 61H
  • 阐明 [后续将具体解说]

    • 84 bytes:
    • 32byte : Debugger Header
    • 4 byte : no man land
    • 4 byte : 对应图中 3,标记数组元素数量
    • 36byte : Demo object
    • 4 * 2 byte : up cookie + down cookie

      • 60H bytes
    • 16 字节对齐

      • 61H bytes
    • 一个字节标记以后内存是否被应用
退出移动版