new、delete和new[]、delete[]

来源:互联网 发布:上海开淘宝店培训 编辑:程序博客网 时间:2024/04/27 11:06

一、简介
new和delete是C++的关键字,不是函数。而且,malloc 申请完空间之后不会对内存进行必要的初始化,而 new 可以。

这两个其实是 C++ 语言标准库的库函数,原型分别如下:

void *operator new(size_t);     //allocate an objectvoid *operator delete(void *);    //free an objectvoid *operator new[](size_t);     //allocate an arrayvoid *operator delete[](void *);    //free an array

二、工作过程
new的工作过程:假设A是一个类型
A *p = new A(10);
第一步:new在内存中找一块可以存放A这个类的空间。
第二部:调用类的构造函数初始化A。
第三部:返回指向新分配并构造的对象的指针。
这里写图片描述
delete的工作过程:
delete *p;
第一步:调用p指向对象的析构函数。
第二部:释放该对象指向的内存。

三、释放和申请一个数组

    int *pi = new int[10]; (1)    string *ps = new string[10]; (2)    A *pa = new A[10]; (3)    delete[] pi; (4)    delete[] ps; (5)    delete[] pa; (6)

申请时,在以上对于(1),分配了存储 10 个 int 对象的内存空间,但并没有初始化。但对于(2)和(3)则调用默认的析构函数初始化每个数组元素。
释放时,对于(4),指直接释放分配的10个int对象的内存空间,但是对于(5)和(6)对10个数组元素分别调用析构函数,然后再释放分配的空间。但是对于(5)和(6)怎么知道有10个元素?怎么知道要调用几次析构函数?
这个问题直接导致我们需要在 new [] 一个对象数组时,需要保存数组的维度,C++ 的做法是在分配数组空间时多分配了 4 个字节的大小,专门保存数组的大小,在 delete [] 时就可以取出这个保存的数,就知道了需要调用析构函数多少次了。
这里写图片描述
从这个图中我们可以看到申请时在数组对象的上面还多分配了 4 个字节用来保存数组的大小,但是最终返回的是对象数组的指针,而不是所有分配空间的起始地址。
因此释放的时候过程如下图:
这里写图片描述

四、为什么new[]和delete[]要配对使用?
如果不配对使用。先使用new[]但后面没有使用delete[]而使用delete的话,则只释放数组的第一个类对象调用了析构函数,后面的两个对象均没调用析构函数,如果类对象中申请了大量的内存需要在析构函数中释放,而你却在销毁数组对象时少调用了析构函数,这会造成内存泄漏。

0 0
原创粉丝点击