CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Aug 2000
    Posts
    1,471

    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.

  2. #2
    Join Date
    Oct 2002
    Location
    Germany
    Posts
    6,205

    Re: Regarding placement new

    Quote 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.

  3. #3
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Regarding placement new

    [ moved thread ]
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  4. #4
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    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
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  5. #5
    Join Date
    May 2002
    Posts
    17

    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.

  6. #6
    Join Date
    Oct 2002
    Location
    Germany
    Posts
    6,205

    Re: Regarding placement new

    Quote 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...
    Quote 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.

  7. #7
    Join Date
    May 2002
    Posts
    17

    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.

  8. #8
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    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()!

  9. #9
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Regarding placement new

    Thanks for your response! Does the order to call delete first or call destructor first really matter?
    Quote 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.

  10. #10
    Join Date
    Oct 2002
    Location
    Germany
    Posts
    6,205

    Re: Regarding placement new

    Quote Originally Posted by dullboy
    Thanks for your response!
    You are welcome!
    Quote 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
  •  





Click Here to Expand Forum to Full Width

Featured