Nana Osaberima Nana Osaberima - 16 days ago 6
C++ Question

Problems with the placement new operator

I understand the placement new operator allows to construct object at a particular/specific memory location. So i tried this;

#include <iostream>
#include <new>

using namespace std;

struct Any {
int x;
string y;
};

int main() {

string mem1[1];
int mem2[5];

Any *p1 = new (mem1) Any;
Any *p2 = new (mem2) Any;

p1->y = "Hello";
//p2->x = 20;

cout << p1->y << endl;
//cout << p2->x;

return 0;
}


What I realized is, I can set a string to a location that I've set aside to hold exactly 1 string but i can't do same for an integer like so;

int mem2[1];
Any *p2 = new (mem2) Any;
p2->x = 20;


I get a buffer overflow error even though it manages to show me the value I placed in that location which is
20
;

enter image description here

Why?

Also, with my full code shown above, I have set aside 2 different memory locations to hold the 2 objects which makes
p1->y
print without any problems. But when i reduce this location

int mem2[5];
to any number below
5
which i think has nothing to do with the location where I placed the string and try to print the string, I get a segmentation fault error. Why
>= 5
? Does it have to do with memory available?

Is there a way to check if using the placement new operator to place an object at a specific memory location was successful?

Answer

You have sets of Undefined Behavior in your code. First of all, there's no guarantee that the declaration string mem[1]; sets aside enough memory to contain an abject of type Any....

Secondly, even if the first had adequate memory to hold such object, the destructor of the array string mem[1]; will still run at the end of main, but you've overwritten that array with something else, hence your program should at best case, crash.

You may want to use a POD type, like char mem1[sizeof(Any)] to store the object, that way you are sure of mem1 being capable enough to store Any, and you'll have no issues with destructor of mem1 being called at the end of main()

Again, you may want to explore a standard facility for this kind of thing, std::aligned_storage

Comments