定位(placement) new

在c++中使用new表达式时实际是执行了3步
1. new表达式调用一个名为 operator new(或者 operator new[])的标准库函数。该函数分配一块足够大的、原始的、未命名的内存空间以便存储特定类型的对象(或者对象数组)
2. 编译器运行相应的构造函数以构造这些对象,并为其传入初始值
3. 对象被分配了空间并构造完成,返回一个只想该对象的指针

使用delete表达式时实际执行了2步
1. 对指针所指向的对象或数组中的元素执行对应的析构函数
2. 编译器调用名为 operator delete(或者 operator delete[])的标准库函数释放内存空间

可以重载 operator new 和 operator delete 以达到控制内存分配的过程,但

void operator new(size_t, void);

是不允许重载的,只供标准库使用。(以上参考自c++ primer)


定位new允许我们在一个特定的、预先分配的内存地址上构造对象,一段简单的事例代码如下

#include <iostream>
#include <string>

int main()
{
    static int a = 0xFF;
    int b = 0xFF;
    int *c = new int(0xFF);

    auto aa = new(&a) int(3);
    std::cout << &a << ","<<aa<< ","<<a << std::endl;
    auto bb = new(&b) int(3);
    std::cout << &b << "," << bb << "," << b << std::endl;
    auto cc = new(c) int(3);//是c不是&c
    std::cout << c << "," << cc << "," << *c << std::endl;

    return 0;
}

运行结果如下

012F1000,012F1000,3
007FFC04,007FFC04,3
00CB3568,00CB3568,3

由此我们可以看出,定位new可以使用堆、栈和静态存储区。值得注意的是,用定位new实例化的类对象在不用时需要显示调用析构函数,但不会释放所在的内存空间。

在频繁创建和删除对象的时候提前开辟一大块内存区域,使用定位new在这里进行操作,或许可以在整体上避免一些内存碎片,并且提高创建的性能,不过怎么标识某块内存里的值已经无效可能还需要一番操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值