If I were you, I would use the placement new and explicitly call the destructor instead of delete .
template< typename D, typename T > D *get_aux_storage( T *x ) { return reinterpret_cast< D * >( x + 1 ); } int main() { char const *hamburger_identity = "yum"; void *hamburger_room = malloc( sizeof( Hamburger ) + strlen( hamburger_identity ) + 1 ); Hamburger *hamburger = new( hamburger_room ) Hamburger; strcpy( get_aux_storage< char >( hamburger ), hamburger_identity ); cout << get_aux_storage< char const >( hamburger ) << '\n'; hamburger->~Hamburger();
Of course, this kind of optimization should only be done after profiling has proven the need. (Do you really save the memory this way? Will it be harder to debug?)
There can be no significant technical difference, but new and delete tell me that the object is created and destroyed, even if the object is just a symbol. When you allocate an array of characters as a common “block”, it uses an array allocator (especially suitable for arrays) and conditionally builds characters in it. Then you should use the new placement to create a new object on top of these characters, which is essentially a smoothing of the objects or a double construction, and then double destruction when you want to delete everything.
It is better to bypass the C ++ object model using malloc / free than to twist it to avoid processing data as objects.
Oh, an alternative is to use a custom operator new , but it might be a worm bank, so I don't recommend it.
struct Hamburger { int tastyness; public: char *GetMeat(); static void *operator new( size_t size_of_bread, size_t size_of_meat ) { return malloc( size_of_bread + size_of_meat ); } static void operator delete( void *ptr ) { free( ptr ); } }; int main() { char const *hamburger_identity = "yum"; size_t meat_size = strlen( hamburger_identity ) + 1; Hamburger *hamburger = new( meat_size ) Hamburger; strcpy( hamburger->GetMeat(), hamburger_identity ); cout << hamburger->GetMeat() << '\n'; }
Potatoswatter
source share