5

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?

MattyZ
  • 1,541
  • 4
  • 24
  • 41
  • 2
    Why do you need this? It does not seem right. – zdf Feb 10 '16 at 17:28
  • @ZDF As it turns out, as I looked at the problem more closely it turns out I likely don't. So the answer to your question seems fairly clear - inexperience... :) – MattyZ Feb 11 '16 at 15:49

5 Answers5

4

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.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

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.

Adi Levin
  • 5,165
  • 1
  • 17
  • 26
  • Why should one use statistical approach when a flag yields guaranteed behavior? – Cheers and hth. - Alf Feb 10 '16 at 16:32
  • @Cheersandhth.-Alf It seems that there is some trivial solution to the problem that you are talking about. I don't get it; maybe you should add an answer to explain what you mean by "a flag". – anatolyg Feb 10 '16 at 16:35
  • I hate classes which have a different (greater) size in debug builds –  Feb 10 '16 at 17:24
1

You could maintain a static table of this pointer values which you mutate in the constructors and destructor to MyClass. Then check this against a particular value of buffer when you need to.

Don't forget to consider the repercussions of move semantics. Will be tricky to get right.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

Not without tracking it yourself.

One solution would be to create a wrapper around std::allocator.

template<class T>
class MyAllocator
{
public:
    T* allocate(std::size_t count = 1) 
    { 
        return allocator_.allocate(count);
    }

    template<class... Args>
    void construct(T* ptr, Args&&... args)
    {
        allocator_.construct(ptr, std::forward<Args>(args)...);
        allocated_ = true;
    }

    bool IsAllocated() const
    {
        return allocated_;
    }

private:
    std::allocator<T> allocator_;
    bool allocated_;

};
Mohamad Elghawi
  • 2,071
  • 10
  • 14
1

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.
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331