Sunday, October 23, 2011

placement new


1. What is placement new? placement new is a overriding version of operator new which I mentioned in my last tips. The placementnew can make it possible to "new" a object on the existing memory. For example, you have a block of memory in your code, which you want to "new" a object on it. You can use placement new.

char* pool=new char[sizeof(Bob)]; //initialize a block of memory
Bob* bob2=new(pool)Bob(2); //"new" a Bob in the pool
You can either "new" Bob on stack or on heap. The example is on the heap.
In fact, the placement new is the step 2 of new operator which I mentioned in my last tips. It just invokes the constructor. Since you cannot invoke the constructor explicitly, you can use placement operator instead. 

2. The problem now is how to release these memory.
I found some materials on the internet which confused me a lot. So I did a sample program myself.

#include<iostream>
#include<new>
using namespace std;

class Bob{
 int index;
 char buffer[7];
public:
 Bob(int i){
  index=i;
  buffer[0]='I';
  buffer[1]=' ';
  buffer[2]='a';
  buffer[3]='m';
  buffer[4]=' ';
  buffer[5]='0'+(char)index;
  buffer[6]='\0';
  cout<<"Bob"<<index<<" is born in constructor"<<endl;
 }
 void Say(){
  cout<<buffer<<endl;
 }
 ~Bob(){
  cout<<"Bob"<<index<<" died in destructor"<<endl;
 }
};

void test(){
 char* pool=new char[sizeof(Bob)]; //on heap
 Bob bob1(1); //on stack
 bob1.Say();
 Bob* bob2=new(pool)Bob(2);
 bob2->Say();
 Bob* bob3=new(&bob1)Bob(3);
 bob3->Say();
 /*
 delete bob2;
 */
 //instead of delete bob2 you can also do the following
 bob2->~Bob();
 delete[] pool;
 //we usaully do the later because placement is usaully used to
 //manage the memory, which means we can declare a block of
 //memory from heap in advance, than manage it, when the program
 //is done, we delete the memory.

 //the stuff in the stack will be released automatically
 //(including destructor)

}

void main(){
 test();
 char a;
 a=getchar();
}

 So 
(1).if the memory is on the heap, we usually invoke the destructor explicitly and then delete the block of memory. This is probably the only situation that need to invoke destructor explicitly.
(2).if the memory is on the stack, let it go. It will invoke your destructor automatically. 


Summary:
This is a good way to manage your memory. Just declare a block of memory, do what you want on it, then delete it.

No comments:

Post a Comment