简体   繁体   English

放置新运算符的问题

[英]Problems with the placement new operator

I understand the placement new operator allows to construct object at a particular/specific memory location. 我理解placement new运算符允许在特定/特定的内存位置构造对象。 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 ; 我收到一个缓冲区溢出错误,即使它设法显示我放置在该位置的值为20 ;

在此输入图像描述

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. 另外,使用上面显示的完整代码,我已经预留了2个不同的内存位置来保存2个对象,这使得p1->y打印没有任何问题。 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. 任何低于5数字,我认为与我放置字符串的位置无关,并尝试打印字符串,我得到分段错误错误。 Why >= 5 ? 为什么>= 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? 有没有办法检查使用placement new运算符将对象放置在特定的内存位置是否成功?

You have sets of Undefined Behavior in your code. 您的代码中有一组未定义的行为。 First of all, there's no guarantee that the declaration string mem[1]; 首先,不能保证声明string mem[1]; sets aside enough memory to contain an abject of type Any .... 留出足够的内存来容纳Any类型的卑鄙....

Secondly, even if the first had adequate memory to hold such object, the destructor of the array string mem[1]; 其次,即使第一个有足够的内存来容纳这样的对象,数组string mem[1];的析构函数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. 仍然会在main的末尾运行,但是你已经用其他东西覆盖了那个数组,因此你的程序应该在最好的情况下崩溃。

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() 您可能希望使用POD类型(如char mem1[sizeof(Any)]来存储对象,这样您就可以确定mem1足以存储Any ,并且您将调用mem1析构函数没有问题在main()的末尾

Again, you may want to explore a standard facility for this kind of thing, std::aligned_storage 同样,您可能想要探索这种事物的标准设施, std::aligned_storage

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM