placement new使用

一、new构造过程

        在使用new关键词创建一个对象指针时,需要做以下工作:

  • 使用operater new分配内存;   A *pa = static<A *>(operator new(sizeof(A)));
  • 然后调用类构造函数;             pa->A();
  • 返回内存指针。                        return pa;

 C++提供了默认的operator new函数共用三个版本:

  1. operator new(size_t); 如果分配内存失败,则抛出异常,同时返回null指针,可以被重载;
  2. operator new(size_t,const std::nothrow_t&) throw();如果失败不抛出异常,返回null指针,可以被重载;
  3. void* operator new (std::size_t size, void* ptr) throw();  该版本为placement new,不能被重载。

在类A中如果重载1、2调用时会调用重载版本,否则会调用系统默认版本。 placement new版本可以将在指定内存中创建对象,ptr就是已分配内存的指针。

二、placement new用法

        placement new使用步骤如下:

  1. 先创建一块内存,该内存足够放下类对象;(const char *constPtr = new char[sizeof(A)];)
  2. 使用placement new函数创建;A *pa = new (constPtr)A;
  3. 显式释放pa;pa->~A();
  4. 如果不用constPtr,释放它; delete []constPtr ;

如下代码:

#include <iostream>
#include <functional>
#include <tuple>
#include <array>
#include "myfunctional.h"
using namespace std;

class B
{
public:
	~B()
	{
		cout << "~B" << endl;
	}
};


class A
{
public:
	A(int _a, string _s) :a(_a), s(_s), b(new B) {}
	~A()
	{
		delete b;
		cout << "~A" << endl;
	}
	void print()
	{
		cout << "a = " << a << ", s = " << s.c_str() << endl;
	}

private:
	int a;
	string s;
	B *b;
};

int main()
{
	char *ptr = new char[sizeof(A)];

	A *pa = new ((void *)ptr)A(4,"cjff");
	pa->print();

	pa->~A();
	delete []ptr;

	system("pause");
	return 0;
}

placement new好处是可以避免频繁new内存,操作过多会有产生大量内存碎片,缺页率会增大,导致程序性能下降和不稳定。

 三、注意事项

        请看下面的使用方式:

int main()
{
	A *ptr = new A(0, "");

	A *pa = new ((void *)ptr)A(4,"cjff");
	pa->print();

	pa->~A();
	delete ptr;

	system("pause");
	return 0;
}

        上面代码在delete ptr处会引起崩溃。原因是因为pa和ptr指针指向了同样一块内存(pa和ptr是是同一个东西),当执行pa->~A(),会删除掉pa中成员b的内存,调用delete ptr会重复删除b指向的内存。  故预分配的内存最好是通过new char[]进行。

参考:

https://blog.csdn.net/linuxheik/article/details/80449059

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值