Leo Heinsaar Leo Heinsaar - 1 month ago 11
C++ Question

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
?

Answer

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
}