C/C++: new,delete 和 malloc,free的却别

C++ 中变量内存的分配分为堆栈(栈)和堆。

堆栈(栈):

在堆栈上分配的内存由程序自行进行管理,当变量超出作用域,标志着变量的生命周期结束,此时程序回收分配的内存。堆栈的生长方式是向上生长。

堆:

堆上的内存由程序员自行管理,分配内存的方式可以是C语言的malloc函数,也可以是C++语言中的new操作符。相对于堆栈,堆中分配的内存需要在变量生命周期结束的地方,由程序员手动回收分配的内存,回收方式可以是C语言的free函数,也可以是C++语言中的delete操作符。堆的生成方向是向下生长。

new,delete和malloc,free的区别:

1. new和delete是C++语言中的操作符,可以被重载;malloc,free是C语言中的函数。

2. new和delete除了可以处理C语言的内建类型,还可以处理C++语言的用户自定义类型;malloc, free是按字节进行处理。

3. new和delete对于用户自定义类型在分配变量内存之后,回收变量内存之前会分别调用自定义类型的构造函数和析构函数;        malloc,free只负责分配和回收指定大小内存,不负责对象的构造和析构。

4. new和delete可以被重载。

在C++中操作符new和delete分别有6种原型:

前四种负责分配内存:

void* operator new(size_t size);
void* operator new[](size_t size);
void* operator new(size_t size, const nothrow_t&) noexcept; //带有nothorw,不抛出异常
void* operator new[](size_t size, const nothrow_t&) noexcept;

下面两种new被成为placement new不分配内存,负责在已分配的内存中构造对象:

void* operator new(size_t size, void* p) noexcept;
void* operator new[](size_t size, void* p) noexcept;

这两个特别的new操作可以在内存池中不需要释放内存的情况下重用内存。

对应的delete也有6种形式:

void operator delete(void* ptr) noexcept;
void operator delete[](void* ptr) noexcept;
void operator delete(void* ptr, const nothrow_t&) noexcept;
void operator delete[](void* ptr, const nothrow_t&) noexcept;
void operator delete(void* p, void*) noexcept;
void operator delete[](void* p, void*) noexcept;

实际中delete只有前两种方式有效。

delete中没有实现抛出异常的机制,所以delete的nothrow版本是多余(未定义),只是为了对应于new的版本进行调用。

delete中的placement版本同样是多余的,因为在delete中不存在内存的分配。

只有当new中,对象的构造函数产生异常时才掉用delete的后四个对应版本,其中placement版本的delete执行的是空操作。


重载operator new 和 operator delete 可以自定义内存的分配和释放,但是不能自定义构造函数和析构函数的调用。也就是构造函数和析构函数的调用是固定的。

#include <iostream>
using namespace std;

class Solution{
public:
	void* operator new(size_t size)
	{
		void* ptr = ::operator new(size);
		cout <<"new :"<< ptr << endl;
		return ptr;
	}
	void* operator new[](size_t size)
	{
		void* ptr = ::operator new[](size);
		cout << "new[] :" << ptr << endl;
		return ptr;
	}
	void* operator new(size_t size, const nothrow_t&) /*noexcept*/
	{
		void* ptr = ::operator new(size, nothrow);
		cout << "new nothrow :"<< ptr << endl;
		return ptr;
	}
	void* operator new[](size_t size, const nothrow_t&) /*noexcept*/
	{
		void* ptr = ::operator new[](size, nothrow);
		cout << "new[] nothrow :" << ptr << endl;
		return ptr;
	}
	void* operator new(size_t size, void* p) /*noexcept*/
	{
		void* ptr = ::operator new(size, p);
		cout << "placement new :" << ptr << endl;
		return ptr;
	}
	void* operator new[](size_t size, void* p)/*noexcept*/
	{
		void* ptr = ::operator new(size, p);
		cout << "placemen new[] :" << ptr << endl;
		return ptr;
	}



	void operator delete(void* ptr) /*noexcept*/
	{
		cout << "delete :" << ptr << endl;
		::operator delete(ptr);
	}
	void operator delete[](void* ptr) /*noexcept*/
	{
		cout << "delete[] :" << ptr << endl;
		::operator delete[](ptr);
	}
	void operator delete(void* ptr, const nothrow_t&) /*noexcept*/
	{
		cout << "delete nothrow :" << ptr << endl;
		::operator delete(ptr, nothrow);
	}
	void operator delete[](void* ptr, const nothrow_t&) /*noexcept*/
	{
		cout << "delete[] nothrow :" << ptr << endl;
		::operator delete[](ptr, nothrow);
	}
	void operator delete(void* ptr, void* p) /*noexcept*/
	{
		cout << "placement delete :" << ptr << endl;
		::operator delete(ptr, p);
	}
	void operator delete[](void* ptr, void* p) /*noexcept*/
	{
		cout << "placement delete[] :" << ptr << endl;
		::operator delete[](ptr, p);
	}
};

int main()
{
	Solution* ptr = new Solution();
	delete ptr;
	Solution* ptr_a = new Solution[5];
	delete[] ptr_a;

	Solution* ptr1 = new (nothrow) Solution();
	delete ptr1;
	Solution* ptr1_a = new (nothrow) Solution[5];
	delete[] ptr1_a;

	Solution* ptr2 = new Solution();
	Solution* ptr3 = new(ptr2) Solution();
	delete ptr3;

	Solution* ptr_a1 = new Solution[5];
	Solution* ptr_a2 = new(ptr_a1) Solution[5];
	delete[] ptr_a2;




	return 0;
}

输出结果:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值