new和delete
1.前言
new和delete是c++在c语言特性上的拓展,功能上与c语言的malloc和free类似,但具体功能上略微有些不同。
1.malloc和free
malloc:
c语言中的malloc()是个函数,函数原型是:void* malloc(unsigned int size) 。
它能够动态的从堆里申请内存,具体实现是交给操作系统来实现的。函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。
我们在使用时,习惯将其返回的类型值进行强转:
char * p = NULL;
p = (char *)malloc(sizeof(char));
free:
而free与malloc相对应,函数原型是:void free(void *);
它能够使传入指针指向的地址空间进行释放,在程序中malloc和free要成对配套使用。
free(p);
2.new和delete
和c语言中的malloc和free功能一样,new能够从堆里动态申请空间,delete能够释放对应空间。malloc、free和new、delete可以交互使用(但不建议),细节上也略微有些不同
首先,new和delete是运算符,不是函数。
1.new的底层也是通过malloc来开辟内存的,new比malloc多一项功能,就是开辟完内存,还可以进行初始化操作:
class Integer
{
public:
Integer()
{
val = new int;
}
~Integer()
{
delete val;
}
private:
int *val;
};
int main(void)
{
Integer *i = new Integer;
}
new语句不仅会在堆上开辟Integer类型大小的一块内存,还会调用Integer类的默认构造函数构造一个对象出来,而malloc无法实现该功能。
2.delete比free多一项功能就是在释放内存之前,还可以析构指针指向的对象,new和delete配对使用,new[]和delete[]配对使用,因此尽量不要交叉使用,特别是为类分配空间,避免出现内存泄漏等问题。
int main(void)
{
Integer *i = new Integer;
delete i;
}
3.new开辟内存失败是抛出bad_alloc类型的异常,因此代码上要捕获该类型的异常才能正确的判断堆内存是否分配成功;malloc内存开辟失败返回的是nullptr指针。
4.new和delete不仅仅是运算符,它们实际上是运算符重载函数的调用,对应的函数名是operator new和operator delete,可以在全局或者类的作用域中提供自定义的new和delete运算符的重载函数,以改变默认的malloc和free内存开辟释放行为,比如说实现内存池。
最后,最重要的一点是:malloc和free不要交互使用!