定位(placement) new

来源:互联网 发布:往string数组添加元素 编辑:程序博客网 时间:2024/04/29 21:32

在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在这里进行操作,或许可以在整体上避免一些内存碎片,并且提高创建的性能,不过怎么标识某块内存里的值已经无效可能还需要一番操作。

0 0
原创粉丝点击