placement new 연산자

13643 단어 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
"; } ~JustTesting() { cout << words << " destroyed
"; } 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:
" << "buffer: " << (void *)buffer << " heap: " << pc2 << endl; cout << "Memory contents:
"; 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:
"; cout << pc3 << ": "; pc3->Show(); cout << pc4 << ": "; pc4->Show(); delete pc2; // free heap1 delete pc4; // free heap2 delete [] buffer; // free buffer cout << "Done
"; 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[]를 버퍼에 사용할 때, 레이아웃 new 조작부호를 사용하여 만든 대상에 분석 함수를 호출하지 않습니다.
두 셀이 중첩되지 않도록 하려면 다음과 같이 하십시오.
pc1 = new (buffer) JustTesting; pc3 = new (buffer + sizeof(JustTesting)) JustTesting("Better Idea", 6);

여기서 포인터 pc3의 상대적 오프셋은 JustTesting 객체의 크기입니다.
두 번째 교훈은placement new 조작부호를 사용하여 대상에게 메모리를 분배하려면 분석 함수가 호출되는 것을 확보해야 하지만 어떻게 확보해야 하는가?
예를 들어, 더미에서 작성된 객체는 다음과 같이 할 수 있습니다.
delete pc2;
그러나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; }

좋은 웹페이지 즐겨찾기