Click to See Complete Forum and Search --> : Regarding placement new


dullboy
November 4th, 2005, 09:38 AM
In my understanding, I think there is two ways to deallocate the memory when we use placement new. For example,

class Foo;
char* p = new char[16];

Foo* pFoo = new(p) Foo;

...

At the end, we might use either pFoo->~Foo() or delete[] p. Is my understanding correct? Thanks for your inputs.

Siddhartha
November 4th, 2005, 01:08 PM
At the end, we might use either pFoo->~Foo() or delete[] p. Is my understanding correct? Thanks for your inputs.One must use both.

While memory allocated using placement new is returned when a delete is done, the destructor of the object is not invoked.

So, one needs to explicitly invoke the destructor for objects constructed using placement new.
class CSomeClass
{
public:
~CSomeClass () {};
char m_pszSomeString [20];
};

int main ()
{
// Allocate desired amount
unsigned char *pBytes = new unsigned char [sizeof (CSomeClass)];

// Use placement new
CSomeClass* pClassObject = new (pBytes) CSomeClass;

// Use pClassObject

// placement new requires explicit destruction
pClassObject->~CSomeClass ();

// Invoke placement delete
delete [] pBytes;

return 0;
} Note that invoking ~CSomeClass () doesn't result in release of allocated memory - delete [] pBytes does.

Marc G
November 4th, 2005, 01:11 PM
[ moved thread ]

Marc G
November 4th, 2005, 01:13 PM
Just like Siddhartha said, you need to call the destructor to destroy the object and then you still need to free the memory allocated with new char[16].

NOTE: Placement new should be avoided as much as possible and should only be used if you know exactly what you are doing. Placement new will not check for properly alignment of your object etc.
Some more information about it can be found at http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10

MarkoBarko
November 4th, 2005, 03:57 PM
What do you guys think of using placement new as a peformance enhancer? Kinda like the following:

void NoPlacementNewTest(int numIterations)
{
for(int i = 0; i < numIterations; i++)
{
SomeClass * pSomeClass = new SomeClass();
delete pSomeClass;
}
}

void PlacementNewTest(int numIterations)
{
char * pBuffer = new char[sizeof(SomeClass)];

for(int i = 0; i < numIterations; i++)
{
SomeClass * pSomeClass = new (pBuffer) SomeClass();
pSomeClass->~SomeClass();
}

delete [] pBuffer;
}

Siddhartha
November 4th, 2005, 04:34 PM
What do you guys think of using placement new as a peformance enhancer? It has certain uses and hence the option exists.

BUT...

Kinda like the following:

void PlacementNewTest(int numIterations)
{
char * pBuffer = new char[sizeof(SomeClass)];

for(int i = 0; i < numIterations; i++)
{
SomeClass * pSomeClass = new (pBuffer) SomeClass();
}

delete [] pBuffer;
}This is certainly NOT correct let alone be an option! I see that the programmer like most C++ developers rarely uses placement new, and has induced a bug by forgetting to invoke the destructor - which in this case needs explicit invocation!

This is one reason why I believe that worries of performance be kept aside; rather good, correct and understandable code be accomplished first!

Optimizing compilers often do a great job in boosting performance. The programmer can concentrate on good programming practices.

MarkoBarko
November 4th, 2005, 07:10 PM
uhh...ok...relax...I didn't forget to call the destructor (especially since I wrote that code 5 SECONDS after I read this thread). SomeClass did not have a destructor in this scenario and calling the implicit one, i figured, was a waste of a line. my apologies and i have made the correction.

btw, i don't see anything that's not understandable about that code. i think it illustrates the point.

Compilers optimize some things. in that example, however, the difference in performance was about 2570% for the placement new scenario. It's not like it was a minor optimization and the compiler would certainly never do something like that.

I just wanted to get a discussion going as far as pitfalls of that scenario.

SuperKoko
November 5th, 2005, 02:58 AM
I am not sure what you want, but it is very very probable that the correct usage is:

void NoNewTest(int numIterations)
{
for(int i = 0; i < numIterations; i++)
{
SomeClass someClass;
// now, use &someClass instead of pSomeClass
}
}

new must be used when we need to define manually the lifetime of the object.

dullboy
November 6th, 2005, 02:34 PM
Thanks for your response! Does the order to call delete first or call destructor first really matter?
One must use both.

While memory allocated using placement new is returned when a delete is done, the destructor of the object is not invoked.

So, one needs to explicitly invoke the destructor for objects constructed using placement new.
class CSomeClass
{
public:
~CSomeClass () {};
char m_pszSomeString [20];
};

int main ()
{
// Allocate desired amount
unsigned char *pBytes = new unsigned char [sizeof (CSomeClass)];

// Use placement new
CSomeClass* pClassObject = new (pBytes) CSomeClass;

// Use pClassObject

// placement new requires explicit destruction
pClassObject->~CSomeClass ();

// Invoke placement delete
delete [] pBytes;

return 0;
} Note that invoking ~CSomeClass () doesn't result in release of allocated memory - delete [] pBytes does.

Siddhartha
November 6th, 2005, 02:37 PM
Thanks for your response!You are welcome! Does the order to call delete first or call destructor first really matter?Sure it does - you are invoking the destructor as if invoking a member function on an object. The object needs to be valid, and doing a delete on the pointer will invalidate it.

Hence, the destructor needs to be invoked first, and the memory needs to be released next - always.