如何正确运用C语言中的placement new操作符?

2026-05-19 23:301阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计945个文字,预计阅读时间需要4分钟。

如何正确运用C语言中的placement new操作符?

C+++ 中 placement new 操作符的使用方法placement new 操作符可以在分配内存时指定内存的位置。下面是一个简化的示例,说明如何使用 placement new 和常规 new 操作符为对象分配内存。

cpp// placenew.cpp#include

int main() { // 使用常规 new 分配内存 int* ptr=new int(10); std::cout << Value of ptr: <

// 使用 placement new 分配内存 int* placementPtr=new(std::nothrow) int[10]; if (placementPtr !=nullptr) { std::cout << Value of placementPtr: <

// 释放内存 delete ptr; delete[] placementPtr;

return 0;}

C++ 中placement new 操作符使用方法

placement new操作符能够在分配内存时指定内存位置。下面的程序使用了placement new操作符和常规new操作符给对象分配内存。

// placenew.cpp -- new, placement new, no delete #include <iostream> #include <string> #include <new> 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\n"; } ~JustTesting() { cout << words << " destroyed\n"; } void Show() const { cout << words << ", " << number << endl; } }; int main(void) { char *buffer = new char [BUF]; // get a block of memory JustTesting *pc1, *pc2; pc1 = new (buffer)JustTesting; // place object in buffer pc2 = new JustTesting("heap1", 20); // place object on heap cout << "Memory block address:\n" << "buffer: " << (void *)buffer << " heap: " << pc2 << endl; cout << "Memory contents: \n"; cout << pc1 << ": "; pc1->Show(); cout << pc2 << ": "; pc2->Show(); JustTesting *pc3, *pc4; pc3 = new (buffer) JustTesting("bad Idea", 6); pc4 = new JustTesting("Heap2", 10); cout << "Memory contents: \n"; cout << pc3 << ": "; pc3->Show(); cout << pc4 << ": "; pc4->Show(); delete pc2; // free heap1 delete pc4; // free heap2 delete [] buffer; // free buffer cout << "Done\n"; return 0; }

执行结果:

[root@localhost 桌面]# ./new Just Testing constructed heap1 constructed Memory block address: buffer: 0x936a008 heap: 0x936a248 Memory contents: 0x936a008: Just Testing, 0 0x936a248: heap1, 20 bad Idea constructed Heap2 constructed Memory contents: 0x936a008: bad Idea, 6 0x936a290: Heap2, 10 heap1 destroyed Heap2 destroyed Done

上面的程序使用placement new操作时存在两个问题。首先,在创建第二个对象时,placement new操作符使用一个新对象来覆盖用于第一个对象的内存单元。显然,如果类动态地为其成员分配内存,这将引发问题。

其次,将delete用于pc2和pc4时,将自动调用为pc2和pc4指向的对象调用析构函数;然而,将delete[]用于buffer时,不会为使用布局new操作符创建的对象调用析构函数。

为确定两个单元不重叠,可以这样做:

pc1 = new (buffer) JustTesting; pc3 = new (buffer + sizeof(JustTesting)) JustTesting("Better Idea", 6);

其中指针pc3相对于pc1的偏移量为JustTesting对象的大小

第二个教训是,如果使用placement new操作符来为对象分配内存,必须确保其析构函数被调用,但如何确保呢?

例如,在堆中创建的对象,可以这样做:

delete pc2;

如何正确运用C语言中的placement new操作符?

然而,对于使用placement new操作符创建的对象,不能像下面一样调用delete

delete pc1; // NO!!!

原因在于delete可与常规new操作符配合使用,但不能与placement new操作符配合使用。

那么我们要显示调用析构函数,必须指定要销毁的对象:

pc3->~JustTesting(); // destroy object pointed to by pc3

int main(void) { char *buffer = new char[BUF]; // get a block of memory JustTesting *pc1, *pc2; pc1 = new (buffer) JustTesting; // place object in buffer pc2 = new JustTesting("Heap1", 20); // place object on heap cout << "Memory block addresses: /n" << "buffer: " << (void *)buffer << " heap: " << pc2 << endl; cout << "Memory contents: "; cout << pc1 << ": "; pc1->Show(); cout << pc2 << ": "; pc2->Show(); JustTesting *pc3, *pc4; // fix placement new location pc3 = new (buffer + sizeof(JustTesting)) JustTesting("better Idea", 6); pc4 = new JustTesting("Heap2", 10); cout << "Memory contents: "; cout << pc3 << ": "; pc3->Show(); cout << pc4 << ": "; pc4->Show(); delete pc2; // free heap1 delete pc4; // free heap2 // explicitly destroy placement new object pc3->~JustTesting(); // destroy object pointed to by pc3 pc1->~JustTesting(); // destroy object pointed to by pc1 delete []buffer; // free buffer cout << "Done/n"; return 0; }

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

本文共计945个文字,预计阅读时间需要4分钟。

如何正确运用C语言中的placement new操作符?

C+++ 中 placement new 操作符的使用方法placement new 操作符可以在分配内存时指定内存的位置。下面是一个简化的示例,说明如何使用 placement new 和常规 new 操作符为对象分配内存。

cpp// placenew.cpp#include

int main() { // 使用常规 new 分配内存 int* ptr=new int(10); std::cout << Value of ptr: <

// 使用 placement new 分配内存 int* placementPtr=new(std::nothrow) int[10]; if (placementPtr !=nullptr) { std::cout << Value of placementPtr: <

// 释放内存 delete ptr; delete[] placementPtr;

return 0;}

C++ 中placement new 操作符使用方法

placement new操作符能够在分配内存时指定内存位置。下面的程序使用了placement new操作符和常规new操作符给对象分配内存。

// placenew.cpp -- new, placement new, no delete #include <iostream> #include <string> #include <new> 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\n"; } ~JustTesting() { cout << words << " destroyed\n"; } void Show() const { cout << words << ", " << number << endl; } }; int main(void) { char *buffer = new char [BUF]; // get a block of memory JustTesting *pc1, *pc2; pc1 = new (buffer)JustTesting; // place object in buffer pc2 = new JustTesting("heap1", 20); // place object on heap cout << "Memory block address:\n" << "buffer: " << (void *)buffer << " heap: " << pc2 << endl; cout << "Memory contents: \n"; cout << pc1 << ": "; pc1->Show(); cout << pc2 << ": "; pc2->Show(); JustTesting *pc3, *pc4; pc3 = new (buffer) JustTesting("bad Idea", 6); pc4 = new JustTesting("Heap2", 10); cout << "Memory contents: \n"; cout << pc3 << ": "; pc3->Show(); cout << pc4 << ": "; pc4->Show(); delete pc2; // free heap1 delete pc4; // free heap2 delete [] buffer; // free buffer cout << "Done\n"; return 0; }

执行结果:

[root@localhost 桌面]# ./new Just Testing constructed heap1 constructed Memory block address: buffer: 0x936a008 heap: 0x936a248 Memory contents: 0x936a008: Just Testing, 0 0x936a248: heap1, 20 bad Idea constructed Heap2 constructed Memory contents: 0x936a008: bad Idea, 6 0x936a290: Heap2, 10 heap1 destroyed Heap2 destroyed Done

上面的程序使用placement new操作时存在两个问题。首先,在创建第二个对象时,placement new操作符使用一个新对象来覆盖用于第一个对象的内存单元。显然,如果类动态地为其成员分配内存,这将引发问题。

其次,将delete用于pc2和pc4时,将自动调用为pc2和pc4指向的对象调用析构函数;然而,将delete[]用于buffer时,不会为使用布局new操作符创建的对象调用析构函数。

为确定两个单元不重叠,可以这样做:

pc1 = new (buffer) JustTesting; pc3 = new (buffer + sizeof(JustTesting)) JustTesting("Better Idea", 6);

其中指针pc3相对于pc1的偏移量为JustTesting对象的大小

第二个教训是,如果使用placement new操作符来为对象分配内存,必须确保其析构函数被调用,但如何确保呢?

例如,在堆中创建的对象,可以这样做:

delete pc2;

如何正确运用C语言中的placement new操作符?

然而,对于使用placement new操作符创建的对象,不能像下面一样调用delete

delete pc1; // NO!!!

原因在于delete可与常规new操作符配合使用,但不能与placement new操作符配合使用。

那么我们要显示调用析构函数,必须指定要销毁的对象:

pc3->~JustTesting(); // destroy object pointed to by pc3

int main(void) { char *buffer = new char[BUF]; // get a block of memory JustTesting *pc1, *pc2; pc1 = new (buffer) JustTesting; // place object in buffer pc2 = new JustTesting("Heap1", 20); // place object on heap cout << "Memory block addresses: /n" << "buffer: " << (void *)buffer << " heap: " << pc2 << endl; cout << "Memory contents: "; cout << pc1 << ": "; pc1->Show(); cout << pc2 << ": "; pc2->Show(); JustTesting *pc3, *pc4; // fix placement new location pc3 = new (buffer + sizeof(JustTesting)) JustTesting("better Idea", 6); pc4 = new JustTesting("Heap2", 10); cout << "Memory contents: "; cout << pc3 << ": "; pc3->Show(); cout << pc4 << ": "; pc4->Show(); delete pc2; // free heap1 delete pc4; // free heap2 // explicitly destroy placement new object pc3->~JustTesting(); // destroy object pointed to by pc3 pc1->~JustTesting(); // destroy object pointed to by pc1 delete []buffer; // free buffer cout << "Done/n"; return 0; }

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!