Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using placement new for a polymorphic unique_ptr

I read this post about using placement new to reset a boost::shared_ptr whilst avoiding additional memory allocations, and assume that the same, if not similar, can be done for a std::unique_ptr? My question is when the std::unique_ptr is of type Base* and so can point to any Derived*, will the placement new work as intended if the Derived classes vary in size? Something like this maybe:

class Base
{
public:
  Base() {}
  virtual ~Base(){}
};

class Foo : public Base
{
public:
  Foo() : Base() {}
  virtual ~Foo(){}
  int a;
  int b;
};

class Bar : public Base
{
public:
  Bar() : Base() {}
  virtual ~Bar() {}
  int a;
};

int main()
{
  std::unique_ptr<Base> bp(new Bar());
  bp->~Base(); //edit: call destructor
  void* rawP = dynamic_cast<void*>(bp.release());//edit: cast to void*
  bp.reset(new(rawP) Foo()); 
  return 0;
}
like image 523
nitronoid Avatar asked Jun 06 '26 15:06

nitronoid


1 Answers

This isn't going to work. A Foo object is simply too big to fit in the memory allocated for a Bar object. If you want bp to point to a Foo object, you're going to have to allocate enough space for one.

Placement new constructs an object in memory you already own. It's on you to make sure that memory is big enough to hold the object you're constructing.

like image 119
Miles Budnek Avatar answered Jun 08 '26 09:06

Miles Budnek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!