深入理解C++定位new
简介
一般的new运算符负责在heap堆中找到一个足以能够满足要求的内存块。
new运算符还有另一种变体:定位new运算符(placement new),它能够让程序员指定要使用的位置。既将new运算符用于提供了的地址。
定位new运算符在头文件new中。
定位new运算符直接使用传递给它的地址,它不负责判断哪些内存单元已被使用,也不查找未使用的内存块。这将一些内存管理的负担交给了程序员。
一个例子:
下面用一个简单的程序来说明定位new的用法:
#include <new> #include <iostream> #include <stdlib.h> using namespace std; int main() { //chunk of memory内存池 char * buffer=(char *)malloc(512*sizeof(char)); int *p1, *p2, *p3, *p4; //常规new: p1 = new int[10]; //定位new: p2 = new (buffer) int[10]; for (int i = 0; i < 10; ++i) p1[i] = p2[i] = 20 - i; cout << "p1 = " << p1 << endl; //常规new指向的地址 cout << "buffer = " << (void *)buffer << endl; //内存池地址 cout << "p2 = " << p2 << endl; //定位new指向的地址 cout << "p2[0] = " << p2[0] << endl; delete []p1; p3 = new (buffer) int; *p3 = 1; cout << "p3 = " << p3 << endl; cout << "p3[0] = " << *p3 << endl; p4 = new (buffer + 10 * sizeof(int)) int; cout << "p4 = " << p4 << endl; cout<<"p2:"<<p2<<" p3:"<<p3<<" p4:"<<p4<<endl;//定位new的地址,都处于内存池中 cout<<"p2:"<<*p2<<" p3:"<<*p3<<" p4:"<<*p4<<endl;//值也符合预期 delete buffer;//释放内存池,定位new出来的指针不用delete,也不能delete cout<<"p2:"<<p2<<" p3:"<<p3<<" p4:"<<p4<<endl;//地址不变 cout<<"p2:"<<*p2<<" p3:"<<*p3<<" p4:"<<*p4<<endl;//但内容已经是内存垃圾 return 0; }
输出结果:
注:为了方便,这里使用malloc提供内存空间。
可以看到,第一次使用定位new时,p2直接使用了我们显示供给的内存。第二次使用定位new时,程序还是直接使用了我们提供的地址,不管它是否已经被使用,而且可以看到新值直接覆盖在旧值上面。
第三次使用定位new时,由于我们提供了相对于buffer的偏移量,所以新的指针指向的地址与buffer首地址偏移了10个int字节。
另外一点要说明的是,不同与常规的new运算符,定位new运算符不需要相应的delete运算符来释放内存。因为它本身就不开辟新的内存。只是在开辟好的指定的内存地址上调用相应的构造函数去构造对象。
工作原理:
简单来说就是定位new运算符只是返回传递给它的地址,并将其强制转换为void *,以便能够赋给任何指针类型。
隐患:
用将定位new运算符来创建新的类对象后,当该对象消亡时,程序并不会自动地调用其析构函数,所以必须显示地调用析构函数。这是少数的需要显示调用析构函数的情况之一。
这里使用了内置类型 int,不需要调用析构函数。若是对象,须显示调用析构函数。
需要注意的是,对于使用定位new运算符创建的对象,应以与创建顺序相反的顺序进行删除。原因在于,晚创建的对象可能依赖于早创建的对象。另外,仅当所有对象都被销毁后,才能释放用于储存这些对象的缓冲区。
- 点赞
- 收藏
- 分享
- 文章举报
- 深入理解C++的new
- C++ 的 new 关键字深入理解
- 深入理解 C++的new
- 深入理解C++的new
- 深入理解C++ new/delete, new []/delete[]动态内存管理
- C++ 中的 new/delete 和 new[]/delete[]深入理解
- 深入理解C++ new/delete, new []/delete[]动态内存管理
- 深入理解C++ New
- 【C++进阶】深入理解C++ new
- C++ 的 new 关键字深入理解
- 深入理解C++的new()
- C++中的定位放置new(placement new)
- 深入理解C++的动态绑定和静态绑定
- 更深入一点理解 switch 语句 及 c/c++ 对 const 的处理
- C++基础学习笔记----第十四课(new和malloc的区别、单例模式等深入)
- 深入理解C++语言--从本质上理解C与C++
- C++基础学习笔记----第十四课(new和malloc的区别、单例模式等深入)
- 深入理解C++的动态绑定和静态绑定
- C++——深入理解sizeof
- 深入理解C++的动态绑定与静态绑定的应用详解