Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if object has been placed using placement new

Using the placement new syntax, I should be able to do something like this:

char *buffer  = new char[sizeof(MyClass)]; //pre-allocated buffer
MyClass *my_class = new (buffer) MyClass; //put da class there 

Now suppose I just do the first line, but not the second. Is there a way that it can be determined in code whether the buffer has been allocated appropriately, but no object of type MyClass has yet been instantiated there?

like image 234
Bitrex Avatar asked Feb 10 '16 16:02

Bitrex


3 Answers

The language doesn't provide any built-in mechanism to provide that information, at least none that I know of. You'll have to add your own bookkeeping code to track such information.

like image 178
R Sahu Avatar answered Oct 03 '22 21:10

R Sahu


For debugging purposes, you can add a special member signature to MyClass and set its value to a constant

class MyClass {
   public:
      MyClass() : signature(762347562374) {}
      bool isValidSignature() const { return signature==762347562374; }
   private:
      unsigned long long signature;
      <other members>
};

Then, check it as follows:

char *buffer  = new char[sizeof(MyClass)]; //pre-allocated buffer
MyClass *my_class = new (buffer) MyClass; //put da class there 
if (my_class->isValidSignature())
   <this means that the object has been allocated correctly, with a high probability>
}

You can put everything that's related to signature, inside a proper #ifdef so that is only runs in debug mode.

like image 26
Adi Levin Avatar answered Oct 03 '22 21:10

Adi Levin


Original code:

char *buffer  = new char[sizeof(MyClass)]; //pre-allocated buffer
MyClass *my_class = new (buffer) MyClass; //put da class there 

To determine dynamically whether the placement new has been performed information about it has to be stored somewhere. The language does not provide that service. So you have to do it yourself, in one of two possible main ways:

  • Storing the info in the buffer.
    For this case the buffer has to be initialized at allocation. E.g. just add () at the end of your new expression. Otherwise there is no way to guarantee that the buffer contents don't look like an object. Two sub-cases:
    1. By adding room for a flag in the buffer.
    2. By having the flag as a member of the object.
      In the case of a polymorphic class there will in practice be a non-zero vtable pointer, which can serve as flag.
  • Storing the info externally.
    For this case the buffer does not need to be initialized at allocation. There are a zillion plus some possibilities, including
    1. A simple bool variable.
    2. A collection of pointers to all such objects.
    3. An audible signal emitted to a chimpanzee, which is later queried.
like image 42
Cheers and hth. - Alf Avatar answered Oct 03 '22 22:10

Cheers and hth. - Alf