operator new和operator delete操作符

定义: operator new和operator delete是系统提供的全局函数;用法与malloc和free相同,功能都是在堆上申请、释放空间;

int* p1 = (int*)operator new (siaeof(int));
operator delete(p1);

operator new实际上是通过malloc来申请空间的,申请成功时直接返回,失败时,会尝试执行空间不足应对措施,若该应对措施用户设置了,则继续申请,否则抛异常;
operator delete实际上是通过调用free释放空间
注意:malloc和operator new用法一样,但是申请空间失败后的方式不一样:malloc失败后返回NULL,operator new失败后抛异常。

new和delete的实现原理

针对内置类型:
new、delete和malloc、free申请空间基本相似;
不同之处在于:new、delete申请、释放的是单个元素空间,new[]、delete[]申请释放的是连续空间;申请空间失败时,malloc返回NULL,operator new抛异常。

针对自定义类型:
new:调用operator new函数申请空间,在申请的空间上执行构造函数,完成对象的构造;
delete:在空间上执行析构函数,完成对象中资源的清理工作,调用operator delete函数释放对象的空间;
newT[N]: 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请,在申请的空间上执行N次构造函数;
delete[]: 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理,调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间。
小结malloc/free和new/delete:

都是在堆上申请空间,需要用户手动释放空间;
malloc/free是函数,new/delete是操作符;
malloc申请的空间不会初始化,new申请的可以初始化;
malloc申请空间时,需要手动计算空间大小传递给(sizeof),new只需要在后面跟上空间类型即可,如果是多个对象,需要在[]中指定对象个数;
malloc返回值为void*,使用时必须进行类型强转;new不需要强转(因为new后直接跟的就是类型);
malloc申请空间失败时返回NULL,使用时必须判空,new不需要判空,它申请失败时会抛异常;
申请自定义对象时,malloc、free只会开辟空间和释放内存;new还会在申请空间之后调用构造函数完成初始化,delete会在释放空间之前调用析构函数完成空间中的资源清理。

当我们在C++中使用new 和delete时,其实执行的是全局的::operator new和::operator delete。首先我们来看一个简单的例子。
class Foo{...}
Foo* pf = new Foo;
delete pf

上面的代码底层执行的是什么呢?首先new包含两阶段的操作。
(1)首先调用::operator new分配内存 (2)调用Foo::Foo() 构造对象内容
然后是delete也分两阶段的操作。
(1)首先调用Foo::~Foo()将对象析构 (2)调用::operator delete释放内存
那么可以对::operator new和::operator delete进行重载么,当然是肯定的
见代码:

#include<iostream>
using namespace std;

class Foo
{
    public:
        int _id;
        long _data;
        string _str;
    public:
        Foo():_id(0){cout<<"default ctor.this="<<this<<" id="<<_id<<endl;}
        Foo(int i):_id(i){cout<<"ctor.this="<<this<<" id="<<_id<<endl;}
        ~Foo() {cout<<"dtor.this="<<this<<" id="<<_id<<endl;}
        static void* operator new(size_t size);
        static void operator delete(void* pdead,size_t size);
        static void* operator new[](size_t size);
        static void operator delete[](void* pdead,size_t size);
};

void* Foo::operator new(size_t size)
{
    Foo* p = (Foo *)malloc(size);
    cout<<"调用了Foo::operator new"<<endl;
    return p;
}

void Foo::operator delete(void *pdead,size_t size)
{
    cout<<"调用了Foo::operator delete"<<endl;
    free(pdead);
}
void* Foo::operator new[](size_t size)
{
    Foo* p  = (Foo*)malloc(size);
    cout<<"调用了Foo::operator new[]"<<endl;
    return p;
}

void Foo::operator delete[](void *pdead, size_t size)
{
    cout<<"调用了Foo::operator delete[]"<<endl;
    free(pdead);
}

int main()
{
    Foo* pf = new Foo(7);
    Foo* pf1 = new Foo[10];
    delete pf;
    delete[] pf1;
}


内存泄漏
定义:
指因为疏忽或错误造成内存未能释放,从而不能再去使用该段内存的情况;
内存泄漏并不是指内存在物理上的消失,而是失去了对该段内存的控制(可以理解为是指针丢了,不是内存丢了),造成了内存空间浪费。
危害:会导致操作系统、服务器等反映越来越慢,最终可能会卡死。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值