new和malloc的区别

@TOC

(1)new和delete是C++的关键字/运算符,malloc与free是c++/c语言的标准函数

(2)malloc需要显式地指定分配的内存大小,new不需要。

(3)new操作符从自由存储区上为对象动态分配内存空间,而malloc函数从上动态分配内存。
【注】凡是通过new操作符进行内存申请,该内存即为自由存储区。

(4)new操作符内存分配成功时,返回对象类型,无须进行类型转换,故new是符合类型安全性的操作符;malloc返回void*,需要通过强制类型转换将void*指针转换成我们需要的类型。

(5)new操作符内存分配失败时,抛出bad_alloc异常;malloc内存分配失败时返回NULL

(6)new操作符有构造函数和析构函数,在开辟空间的同时,会调用自定义对象的构造函数来完成初始化;malloc只会开辟空间。

(7)malloc分配空间后,可以通过realloc扩张内存;new操作符则不能进行再次扩张内存的操作。

(8)new相对malloc效率要低,因为new的底层封装了malloc。

【注】C++允许重载new/delete操作符。

【注】new在底层怎么实现的?
new操作符是把构造函数实例化成一个对象
编译器在转换的时候调用了一个函数:opreator new,而这个函数恰恰就是new的底层实现!

void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
        {       // try to allocate size bytes
        void *p;
        while ((p = malloc(size)) == 0)
                if (_callnewh(size) == 0)
                {       // report no memory
                static const std::bad_alloc nomem;
                _RAISE(nomem);
                }

        return (p);
        }

operator new函数本质也是封装了malloc的函数,并且当申请内存空间失败的时候不再是返回NULL,而是抛出异常!
new的工作原理
底层调用operator new函数进行空间的申请,申请到空间以后,调用对应的类的构造函数进行初始化
delete的底层实现原理
调用的就是operator delete函数,对应的就是封装了free的函数

注意:这里的operator new并不是对new的重载!这个operator new是一个单独的函数,如果需要调用就要显式写出opreator new!

//显示调用operator new
#include<iostream>
using namespace std;
int main()
{
    int* pa = new int;
    //显式调用必须这样!
    void* pa = operator new(sizeof(int));
    return 0;
}

【注】用new分配一个数组之后,之后用delete[]释放掉,那这个delete怎么知道应该释放多大一片内存呢?
new int[10]时,malloc本应该申请10个A类型大小的空间,也就是40个字节,但是此时malloc实际上申请了44个字节,new返回的指针是malloc返回的指针向后偏移4个字节的地址
这4个字节存放着所申请自定义元素的个数。

delete[]的原理: delete[]会把new[]所返回的指针向前偏移4个字节的地址返回给free,因此free就能正确的释放掉整片空间。

多出来4个字节保存着自定义元素的个数的作用:
一个对象在释放空间前需要调用析构函数来完成一些资源的清理工作。那么问题来了,delete[] 没有像new A[10]传参进去,delete[]怎么知道调用多少次析构。其实多出来的4个字节存的元素个数,就是用来让delete[]知道调用多少次析构函数的

【注】对于没有自定义析构器的class或者struct,在delete时不需要调用其析构器,
所以可以将整块数组当成一个整体来处理,也就可以使用delete直接释放这一整块内存空间。

【注】而对于自定义了析构器的class或者struct,在delete时需要逐个调用其析构器,
所以需要有标识位记录数组大小,然后通过数组大小来逐个调用其析构器,再释放内存。
互联网学习 文章被收录于专栏

互联网知识点

全部评论
感谢楼主分享,很有用
3 回复 分享
发布于 2022-08-30 09:09 江苏

相关推荐

11-26 22:34
已编辑
重庆邮电大学 Java
快手 客户端开发 (n+5)k*16 公积金12
牛客895077908号:佬 什么双非硕啊
点赞 评论 收藏
分享
3 28 评论
分享
牛客网
牛客企业服务