[英]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.