new / delete,new[ ] / delete[ ],operator new /operator delete,malloc / free 之间的区别和联系

1. C语言和C++中动态内存分配的区别

区别C语言C++
申请内存mallocnew 和new[]
释放空间freedelete 和delete[]
作用域内置类型所有类型

new / delete 是两个操作符,malloc / free是两个系统函数



2. new / delete 是如何实现操作的?

new 两步操作delete 两步操作
1).调用 :: operator new( )分配内存1).调用该类的析构函数释放所占资源
2).调用该类的构造函数进行初始化2).调用 :: operotor delete( )释放内存

这里写图片描述



3. operator new / operator delete

先来看看两个函数的调用方式:

void* operator new (size_t)
//用new 申请一块size_t大小的内存,需要该空间的返回值,来判断内存是否申请成功

void operator delete(void*)
//用delete 释放一块空间,不需要返回值,但需要参数指明释放那一块空间,得保证你释放的空间存在
  • operator new 更具体的形式,有如下三种:(稍作了解)
//异常抛出形式:
void* operator new(std::size_t size) throw(std::bad_alloc);

//不抛出异常形式:
void* operator new(std::size_t size,const std::nothrow_t& nothrow_value) throw();

//placement形式:
void* operator new(std::size_t size,void*ptr)throw();

使用new / delete 函数时,编译器会默认调用 operator new ( ) 和 operator delete( ),但既然是函数,就可以实现重载

代码验证:

#include<iostream>
using namespace std;

class A
{
public:
    A()
    {
        cout << "A constructor" << endl;
    }
    void* operator new(size_t size)
    {
        cout << "this is new A" << endl;
        return ::operator new(size);
    }

    void  operator delete(void* ptr)
    {
        cout << "this is delete A" << endl;
        return ::operator delete(ptr);
    }

    ~A()
    {
        cout << "A destructor" << endl;
    }
};

int main()
{
    A *a = new A;
    delete a;
    system("pause");
    return 0;
}

打印结果:
这里写图片描述

  • operator new 申请一个内存失败时,它会进行如下操作:

    1)如果存在客户规定的处理函数,则调用处理函数(new_handler),如果不存在,抛出异常。
    ——new_handler 的模型为:void(*new_hanlder)( )

    2)继续申请内存
    3)判断是否申请成功,如果成功——返回内存指针,如果失败——转向步骤1)

  • operator的注意事项:
    1)重载时,-必须带void* 类型的返回值
    2)重载时,-必须带有你申请内存 size_t 大小的参数
    3)重载时,可以调用除 sizez-t 以外的其他参数


5. new[ ] / delete[ ]

  • new[]如何分配空间的?

会额外多分配四个字节存储数组元素个数,分配完成后指针会向后偏移4个字节。
这里写图片描述


这里写图片描述

  • delete[]如何释放正确的空间大小?

将指针向前偏移4个字节,获取元素个数,再挨个释放。

这里写图片描述



6. delete / delete[ ] 的区别

区别deletedelete[ ]
释放对象new分配的单个对象的指针指向的空间new分配的数组的指针指向的空间
操作步骤调用这个对象的析构函数释放所占资源,再释放这段内存空间调用数组中每一个元素的析构函数释放资源,再释放这段内存空间
单个类对象可以使用可以使用(有一个就调一次析构函数)
数组对象不可使用(此时只调用下标为0 的那个元素的析构函数)可以使用

代码分析:
(1)

//实例一:
int*p=new int;(内置类型不需要调析构函数和构造函数)
delete p;//可以,p指向了一个int的内置类型大小的空间,delete直接释放了它。
delete []p;//可以

这里写图片描述

这里写图片描述


(2)

//实例二:
int*p=new int[10]();可以
delete p;内置类型不需要调析构函数
delete []p;可以,效果同上

delete p;
这里写图片描述
delete [ ]p;
这里写图片描述


(3)

//实例三:
A*p=new A();
delete p;//可以
delete []p;//可以

delete p;
这里写图片描述
delete [ ]p;
这里写图片描述


(4)

//实例四:
A*p=new A[2]();
delete p;//不行,只会调用p[0]的析构函数
delete[] p;可以,会调每个数组元素的析构函数

delete p;
这里写图片描述
delete [ ]p;
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值