How to determine if an asset was placed using a new placement

Using the new layout syntax, I would have 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'm just doing the first line, but not the second. Is there a way in which it can be defined in the code, is the buffer allocated correctly, but not a single object of type MyClass has been created there yet?

+5
source share
5 answers

Source:

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

To dynamically determine whether a new placement has been performed, information about it must be stored somewhere. Language does not provide this service. Therefore, you must do it yourself, in one of two possible ways:

  • Saving information in the buffer.
    For this case, the buffer must be initialized during allocation. For instance. just add () to the end of your new expression. Otherwise, it is impossible to guarantee that the contents of the buffer will not look like an object. Two subsectors:
    • Adding a place for the flag in the buffer.
    • The presence of a flag as an object of the object.
      In the case of a polymorphic class, in practice there will be a non-zero pointer vtable, which can serve as a flag.
  • Saving information from the outside.
    For this case, the buffer does not need to be initialized during allocation. There are a million plus some features, including
    • Simple bool variable.
    • A collection of pointers to all such objects.
    • The sound signal emitted by the chimpanzee, which is later requested.
+1
source

The language does not provide a built-in mechanism for providing this information, at least, of what I know. You will need to add your own accounting code to track such information.

+4
source

For debugging purposes, you can add a special signature element 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 related to the signature inside the correct #ifdef , so that it only works in debug mode.

+2
source

You can save a table of static values ​​for the this pointer, which you mutate in constructors and destructors on MyClass . Then check this for a specific buffer value when you need to.

Remember to consider the consequences of the semantics of movement. It will be difficult to understand.

+1
source

Do not trace 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_; }; 
+1
source

Source: https://habr.com/ru/post/1242714/


All Articles