C++内存管理—new、delete

1.new和delete


  new的内部执行顺序:  

    [1]调用operator new函数,该函数里面调用malloc申请内存。

    [2]调用类的构造函数。

  delete的内部执行顺序:

    [1]调用类的析构函数。

    [2]调用operator delete函数,该函数里面调用free释放内存。

  operator new和operator delete函数可以重载,这两个函数的声明在文件:/usr/include/c++/4.8.2/new。

2.new[]和delete[]


  如果有显式的析构函数时,使用new[]申请内存时,会在前面多分配4个字节用来保存数组大小,在 delete[]的时候会依次逆序调用数组中各对象的析构函数;如果没有显式的析构函数时,使用new[]申请内存时,不会在前面多分配4个字节。

  new[10]的内部执行顺序:

    [1]先调用operator new[]函数,里面调用malloc分配4字节(有显式构造函数时) + 10个对象大小的内存。

    [2]然后在前四个字节写入数组大小(有显式构造函数时)。

    [3]最后调用10次构造函数。

  delete[]的内部执行顺序:

    [1]根据最前面的4个字节得到对象个数,调用n次类的析构函数。(有显式构造函数时)

    [2]调用operator delete[]函数,里面调用free释放4字节(有显式构造函数时) + 10个对象大小的内存。

  【1】如果是调用了A *p = new A[10];时:

    如果此时没有显式的构造函数,则:不管是调用delete p;还是delete[] p;都会释放数组的内存。不同的是调用delete p,只会对第一个元素调用析构函数,但此时的析构函数是空函数(如果类中无析构函数,则编译系统会默认补上一个空的析构函数),因此也不会造成内存泄漏。

    如果此时有显式的构造函数,则调用delete p时程序崩溃,因为p的前4个字节处才是申请内存的起始位置。

  【2】如果是调用了A *p = new A;时:

    如果此时没有显式的构造函数,则:不管是调用delete p;还是delete[] p;都会释放p的内存,并且都会调用一次A的析构函数(空函数)。

    如果此时有显式的构造函数,则调用delete[] p时程序崩溃,因为这个会从p向前取4个字节作为元素个数,而申请时没有申请这4个字节。

  因此,从上面的分析看,混用delete和delete[]只会导致程序可能崩溃,没有哪种情况会导致内存泄漏。

 

 

 

posted on 2019-03-08 15:52  能量星星  阅读(300)  评论(0编辑  收藏  举报

导航