c++ New和Delete详解

了解operator new和 operator delete

在库中有两个函数分别是operator new和operator delete。我们知道new作用之一是开辟空间,其底层还是调用了malloc,但与malloc不一样的是当机器执行空间申请操作失败后,malloc返回了一个NULL指针,而new的反应则是抛异常以提供捕获,因此虽然new原则上是调用了malloc,但更进一步说,new是调用了malloc的封装函数operator new,然后再执行类的构造函数,相应的delete是调用了析构函数再调用free的封装函数operator delete,其中operator delete就包含了free。

匹配使用

与new匹配的是delete,new[]匹配的是delete[],以及c语言中malloc和free当二者没有匹配时是否会带来影响?

在这里需要了解delete的原理,当对象的类型为内置类型时,其实没有匹配使用不会带来什么影响(IDE以vs2019为例,注:不同的编译器可能有不同的结果,本次演绎仅供参考)。

int main()
{
    int* a = new int;

    free(a);
    delete a;
    delete[] a;

    return 0;
}

以上三种方式销毁并没有带来编译器报错,但是这仅仅是对于内置类型!!对于自定义的类,类型不匹配带来的错误时未定义的,而这个问题在被自定义了具有析构函数后尤为明显。

class A
{
public:
    A()
        :_a(0)
    {}

    ~A()
    {
        _a = 0;
        cout << "~A()" << endl;
    }
private:
    int _a = 0;
};

int main()
{
    // new[] 类型定义对象pst
    A* pst = new A[10];

    // 使用delete 释放pst指向的空间
    delete pst;

    return 0;
}

new了十个A类型的对象,最后释放却使用delete,运行结果是这样的

 原因就在于new[]在申请空间时,不仅仅申请了指定了10个整形的空间,在这些空间之前,编译器默认申请了四个字节的空间用于保存数字10,然后返回了之后十个空间的指针;这样做是为了之后调用delete[]时,指针向前偏移后获取该int类型里的数据,以便编译器判断进行多少次的析构函数。而最后却调用了delete释放空间,直接引起了指针的误差导致错误。

再次强调--使用的过程务必--匹配使用!!!!

显示调用构造函数——定位new(placement-new)

定位 new 表达式是在 已分配的原始内存空间中调用构造函数初始化一个对象
使用格式:
new (place_address) type 或者 new (place_address) type(initializer-list)
place_address 必须是一个指针, initializer-list 是类型的初始化列表
定位 new 表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如
果是自定义类型的对象,需要使用 new 的定义表达式进行显示调构造函数进行初始化。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值