C++ 定位new运算符
这里说的定位new运算符,是一种相对于普通的new运算符,可以指定内存地址的运算符,程序直接使用我们提供的地址,不管它是否已经被使用,而且可以看到新值直接覆盖在旧值上面。
定位new运算符直接使用传递给它的地址,它不负责判断哪些内存单元已被使用,也不查找未使用的内存块
由于本质上定位new运算符并不开辟新的内存,也就不应该用delete去释放它
单来说就是new运算符只是返回传递给它的地址,并将其强制转换为void *,以便能够赋给任何指针类型。
#include<iostream> #include<string> using namespace std; const int BUF = 512; class JustTesting { private: string words; int number; public: JustTesting(const string& s = "Just Testing", int n = 0) { words = s; number = n; cout << words << " constructed" << endl; } ~JustTesting() { cout << words << " destroyed" << endl; } void show() const { cout << words << " ," << number << endl; } }; int main() { char* buffer = new char[BUF]; JustTesting *pc1, *pc2; pc1 = new(buffer)JustTesting; pc2 = new JustTesting("Heap1", 20); cout << "Memory block address" << endl << "buffer: " << (void*)buffer << " heap: " << pc2 << endl; cout << pc1 << ": "; pc1->show(); cout << pc2 << ": "; pc2->show(); JustTesting *pc3, *pc4; //pc3 = new (buffer)JustTesting("Bad Idea", 6); //pc3直接占用了pc1的内存区域,这样一来如果pc1中有new分配的成员变量,将造成内存泄漏, //因此更好的方式是 pc3 = new (buffer+sizeof(JustTesting)) JustTesting("Better Idea",6); pc4 = new JustTesting("Heap2", 10); cout << "Memory Contents" << endl; cout << pc3 << ": "; pc3->show(); cout << pc4 << ": "; pc4->show(); delete pc2; delete pc4; //由于delete buffer并不会出发buffer内对象的析构函数,所以只能手动调用其析构函数 //需要注意调用析构函数的顺序,由于晚创建的对象可能依赖早创建的对象,因此析构的顺序应该与创建顺序相反,另外,仅当析构了所有对象之后,才能释放用于存储这些对象的缓冲区 pc3->~JustTesting(); pc1->~JustTesting(); delete[] buffer; //delete pc1; 因为buffer和pc1实际上指向同一个地址,因此如果注释掉上面一行,打开这里,也可以正常运行,但逻辑上却是没有道理的 cout << "done" << endl; cin.get(); return 0; }