繁体   English   中英

C++ unordered_map 初始化读访问冲突

[英]C++ unordered_map initialization read access violation

我有一个结构:

struct Foo
{
    std::unordered_map<std::string, std::string> info;
    int count;
    int bar;
}

我试图在堆上初始化这个结构,如下所示:

Foo* createFoo(int count, int bar)
{
    Foo* foo = (Foo*)malloc(sizeof(Foo));
    foo->info = std::unordered_map<std::string, std::string>(); // <- exception thrown here
    foo->count = count;
    foo->bar = bar;
    return foo;
}

我在构建unordered_map抛出以下异常:

Exception thrown: read access violation. _Pnext was 0xCDCDCDD1.

我知道 MVS 用0xCD填充堆分配的内存,这就是_Pnext指针具有此值的原因,但我不明白为什么unordered_map构造函数没有将这些字段清零。

我意识到现代 C++ 这样做的方式是使用new / 构造函数,但我试图用(基本上)POD 对象以非 OOP 程序方式编写此代码。

我是否错误地初始化了地图?

malloc的AC调用

Foo* foo = (Foo*)malloc(sizeof(Foo));

不为数据成员调用构造函数。

所以数据成员

std::unordered_map<std::string, std::string> info;

没有建造。

和这个带有复制赋值运算符的语句

foo->info = std::unordered_map<std::string, std::string>();

导致未定义的行为,因为没有创建对象foo->info

您必须使用运算符 new 而不是 malloc。

例如

Foo* foo = new Foo();

malloc()不初始化分配的内存,这在分配具有非平凡构造函数的对象时很糟糕。

你应该使用new代替。

Foo* foo = new Foo;

要释放通过new分配的对象,可以使用delete

delete pointe_to_object;

malloc()不创建任何对象。 它只是保留了一些未初始化的内存。 该内存中没有对象,必须使用放置new创建这些对象。

现在, operator=需要一个现有对象,因为它是一个成员函数(总是)。 通过在foo->info = std::unordered_map<std::string, std::string>()行上调用此运算符,您可以在不存在的对象上调用运算符。

解决方案是不要违背语言并按照您的预期使用new

Foo* createFoo(int count, int bar)
{
    Foo* foo = new Foo;
    // unnecessary now, the object is already constructed and default-initialized
    // foo->info = std::unordered_map<std::string, std::string>(); 

    // ints are constructed, but not initialized
    foo->count = count;
    foo->bar = bar;
    return foo;
}

您也可以将malloc与放置new一起使用,但这仅在您需要没有实际对象的内存时才有用(例如在向量实现中)。


注意:在现代 C++ 中使用 raw new很糟糕(嗯,9 岁了,但和std::unordered_map一样现代)。 请改用智能指针和 STL 容器。

暂无
暂无

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

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