3

I recently ran into an unusual use of the new operator to re-initialise a C++ class, the code is as follows:

#include <iostream>
struct Test { Test() { std::cout<<"Test Ctor\n"; }  };
int main()
{
  Test t ;
  new (&t) Test;
  return 0 ;
}

If this code is run, the Test ctor is called twice. In this case it appears that the 'new' operator is using the pointer to the object as the source of the memory rather than allocating new memory, valgrind comfirms no memory leaks.

Can someone shed some light on this use of the 'new' operator?

Gearoid Murphy
  • 11,834
  • 17
  • 68
  • 86

2 Answers2

5

This operator is called placement new. It runs the constructor of the object at the given addresss without prior memory allocation. It could be used when allocating a large array first, then constructing many object on it, for instance.

qdii
  • 12,505
  • 10
  • 59
  • 116
  • It is actually used ubiquitously all over the standard library in dynamic containers (through the allocators). – Kerrek SB Feb 25 '12 at 17:43
  • 2
    This is not a valid use though, unlike the standard library uses. This is constructing over an existing, live object. – smparkes Feb 25 '12 at 17:50
  • @KerrekSB PODs don't have user-declared constructors. – smparkes Feb 25 '12 at 18:24
  • @smparkes: Hm, yes... but there's something (see the chapet about "object lifetime") along the lines of it only being UB if the program depends on the destructor having run, so I have a feeling that the present code is actually OK. But you're right, `Test` is not POD. – Kerrek SB Feb 25 '12 at 18:28
3

It's called "placement new" and is usually used to construct an object in a specific memory location rather than the default returned by malloc.

It's not supposed to be used this way (double construction) and the standard doesn't say what the behavior of using it this way will be.

That said, at least in the past. the global iostreams used to rely on this double construction. (But that still doesn't make it a good idea.)

smparkes
  • 13,807
  • 4
  • 36
  • 61
  • It's true that re-constructing objects is a difficult business, but I think in this case probably it is defined behavior, since the class `Test` is trivially destructable. I might be wrong though, and even if I'm right I don't advise it. – Steve Jessop Feb 25 '12 at 17:32
  • @SteveJessop If this were raw memory that was alloc'd normally, you might get away with saying it was okay. But doing it on top of a object that compiler allocated/initialized I think is undefined. – smparkes Feb 25 '12 at 17:36
  • @SteveJessop even in raw allocated memory, I suspect it's not okay. It certainly violates balancing constructors and destructors. – smparkes Feb 25 '12 at 17:41