c++ new, operator new, placement new

c++ new 用于动态分配内存。比如 A* a=new A();其实这里一共有三步:

1、分配sizeof(A)的内存,这里的分配是通过operator new(std::size_t)实现的

2、在分配的内存上初始化,调用A的构造函数

3、返回相应指针

某些时候我们需要重载operator new来达到一些目的,如内存泄漏检查。

一、operator new重载

需要注意几个问题:

1、应该实现handle_new,即分配内存不成功时的措施。

2、第一个参数应该是std::size_t

3、一般不重载placement new,placement new本身就是operator new的一种标准重载形式

4、重载operator new后要实现相应的operator delete,不过只有分配内存失败时才会调用重载的delete,或者还是会调用全局delete

重载实例

#include <iostream>
#include <string>
using namespace std;

class X
{
public:
    X() { cout<<"constructor of X"<<endl; }
    ~X() { cout<<"destructor of X"<<endl;}

    void* operator new(size_t size,string str)
    {
        cout<<"operator new size "<<size<<" with string "<<str<<endl;
        return ::operator new(size);
    }

    void operator delete(void* pointee)
    {
        cout<<"operator delete"<<endl;
        ::operator delete(pointee);
    }
private:
    int num;
};

int main()
{
    X *px = new("A new class") X;
    delete px;

    return 0;
}

二、placement new

placement new可以在指定的内存空间上构造对象,它的原型为:

void * operator new(std::size_t,void *p){
        return p;
}

使用方式如下:

new(ptr) A();其中ptr为已分配好的内存。

Placement new使用步骤

在很多情况下,placement new的使用方法和其他普通的new有所不同。这里提供了它的使用步骤。

第一步  缓存提前分配

有三种方式:

1.为了保证通过placement new使用的缓存区的memory alignment(内存队列)正确准备,使用普通的new来分配它:在堆上进行分配
class Task ;
char * buff = new [sizeof(Task)]; //分配内存
(请注意auto或者static内存并非都正确地为每一个对象类型排列,所以,你将不能以placement new使用它们。)

2.在栈上进行分配
class Task ;
char buf[N*sizeof(Task)]; //分配内存

3.还有一种方式,就是直接通过地址来使用。(必须是有意义的地址)
void* buf = reinterpret_cast<void*> (0xF00F);

第二步:对象的分配

在刚才已分配的缓存区调用placement new来构造一个对象。
Task *ptask = new (buf) Task

第三步:使用

按照普通方式使用分配的对象:

ptask->memberfunction();

ptask-> member;

//...

第四步:对象的析构

一旦你使用完这个对象,你必须调用它的析构函数来毁灭它。按照下面的方式调用析构函数:
ptask->~Task(); //调用外在的析构函数

第五步:释放

你可以反复利用缓存并给它分配一个新的对象(重复步骤2,3,4)如果你不打算再次使用这个缓存,你可以象这样释放它:delete [] buf;

三、operator new[]

new[]和new类似,仍然会优先调用类中重载的operator new[]。另外还要注意的是,在operator new[](size_t size)中传入的并不是sizeof(A)*num。而要在对象数组的大小上加上一个额外数据,用于编译器区分对象数组指针和对象指针以及对象数组大小

原文地址:https://www.cnblogs.com/coderht/p/7206283.html