Search code examples
c++stacknew-operatorheap-memoryplacement-new

Is it okay to give a stack object address to placement new?


Ignoring usefulness of such practice. (Though real-life examples are welcome, of course.)

For example, the following program outputs the correct value for a:

#include <iostream>

using namespace std;

int main()
{
  int a = 11111;
  int i = 30;

  int* pi = new (&i) int();

  cout << a << " " << endl;
}

But isn't new-allocation supposed to create some bookkeeping information adjacent to i (for correct subsequent deallocation), which in this case is supposed to corrupt the stack around i?


Solution

  • Yes, it's perfectly OK to perform placement-new with a pointer to an object on the stack. It will just use that specific pointer to construct the object in. Placement-new isn't actually allocating any memory - you have already provided that part. It only does construction. The subsequent deletion won't actually be delete - there is no placement delete - since all you need to do is call the object's destructor. The actual memory is managed by something else - in this case your stack object.

    For example, given this simple type:

    struct A {
        A(int i) 
        : i(i)
        {
            std::cout << "make an A\n";
        }
    
        ~A() {
            std::cout << "delete an A\n";
        }
    
        int i;
    };
    

    The following is completely reasonable, well-behaved code:

    char buf[] = {'x', 'x', 'x', 'x', 0};
    std::cout << buf << std::endl;  // xxxx
    auto a = new (buf) A{'a'};      // make an A
    std::cout << a->i << std::endl; // 97
    a->~A();                        // delete an A
    

    The only case where this would be invalid would be if your placement-new-ed object outlasts the memory you new-ed it on - for the same reason that returning a dangling pointer is always bad:

    A* getAnA(int i) {
        char buf[4];
        return new (buf) A(5); // oops
    }