|
-
November 4th, 2005, 10:38 AM
#1
Regarding placement new
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.
-
November 4th, 2005, 02:08 PM
#2
Re: Regarding placement new
 Originally Posted by dullboy
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.
Code:
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.
Last edited by Siddhartha; November 4th, 2005 at 02:12 PM.
-
November 4th, 2005, 02:11 PM
#3
Re: Regarding placement new
-
November 4th, 2005, 02:13 PM
#4
Re: Regarding placement new
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-lit...html#faq-11.10
-
November 4th, 2005, 04:57 PM
#5
Re: Regarding placement new
What do you guys think of using placement new as a peformance enhancer? Kinda like the following:
Code:
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;
}
Last edited by MarkoBarko; November 4th, 2005 at 08:11 PM.
-
November 4th, 2005, 05:34 PM
#6
Re: Regarding placement new
 Originally Posted by MarkoBarko
What do you guys think of using placement new as a peformance enhancer?
It has certain uses and hence the option exists.
BUT...
 Originally Posted by MarkoBarko
Kinda like the following:
Code:
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.
Last edited by Siddhartha; November 4th, 2005 at 05:49 PM.
-
November 4th, 2005, 08:10 PM
#7
Re: Regarding placement new
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.
-
November 5th, 2005, 03:58 AM
#8
Re: Regarding placement new
I am not sure what you want, but it is very very probable that the correct usage is:
Code:
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.
"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
Club of lovers of the C++ typecasts cute syntax: Only recorded member.
Out of memory happens! Handle it properly!
Say no to g_new()!
-
November 6th, 2005, 03:34 PM
#9
Re: Regarding placement new
Thanks for your response! Does the order to call delete first or call destructor first really matter?
 Originally Posted by Siddhartha
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.
Code:
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.
-
November 6th, 2005, 03:37 PM
#10
Re: Regarding placement new
 Originally Posted by dullboy
Thanks for your response!
You are welcome!
 Originally Posted by dullboy
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|