[英]C++ unordered_map initialization read access violation
I have a struct:我有一个结构:
struct Foo
{
std::unordered_map<std::string, std::string> info;
int count;
int bar;
}
I am trying to initialize this struct on the heap as follows:我试图在堆上初始化这个结构,如下所示:
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;
}
I am getting the following exception thrown upon construction of the unordered_map
:我在构建unordered_map
抛出以下异常:
Exception thrown: read access violation. _Pnext was 0xCDCDCDD1.
I understand that MVS fills heap allocated memory with 0xCD
which is why the _Pnext
pointer has this value, but I don't understand why the unordered_map
constructor isn't zero-ing these fields out.我知道 MVS 用0xCD
填充堆分配的内存,这就是_Pnext
指针具有此值的原因,但我不明白为什么unordered_map
构造函数没有将这些字段清零。
I realize that the modern C++ way of doing this is with new
/constructors but I am trying to write this code in a non-OOP procedural way with (basically) POD objects.我意识到现代 C++ 这样做的方式是使用new
/ 构造函数,但我试图用(基本上)POD 对象以非 OOP 程序方式编写此代码。
Am I initializing the map incorrectly?我是否错误地初始化了地图?
AC call of malloc malloc的AC调用
Foo* foo = (Foo*)malloc(sizeof(Foo));
does not invoke constructors for data members.不为数据成员调用构造函数。
So the data member所以数据成员
std::unordered_map<std::string, std::string> info;
was not constructed.没有建造。
And this statement with the copy assignment operator和这个带有复制赋值运算符的语句
foo->info = std::unordered_map<std::string, std::string>();
results in undefined behavior because there is not created the object foo->info
.导致未定义的行为,因为没有创建对象foo->info
。
You have to use the operator new instead of malloc.您必须使用运算符 new 而不是 malloc。
For example例如
Foo* foo = new Foo();
malloc()
do not initialize allocated memory and this is bad when allocating objects that have non-trivial constructors. malloc()
不初始化分配的内存,这在分配具有非平凡构造函数的对象时很糟糕。
You should use new
instead.你应该使用new
代替。
Foo* foo = new Foo;
To deallocate objects allocated via new
, you can use delete
.要释放通过new
分配的对象,可以使用delete
。
delete pointe_to_object;
malloc()
doesn't create any object. malloc()
不创建任何对象。 It just reserves some uninitialized memory.它只是保留了一些未初始化的内存。 There are no objects in that memory, those would have to be created with placement new
.该内存中没有对象,必须使用放置new
创建这些对象。
Now, operator=
requires an existing object, because it's a member function (always).现在, operator=
需要一个现有对象,因为它是一个成员函数(总是)。 By calling this operator on line foo->info = std::unordered_map<std::string, std::string>()
you call operator on non-existing object.通过在foo->info = std::unordered_map<std::string, std::string>()
行上调用此运算符,您可以在不存在的对象上调用运算符。
The solution is to not go against the language and use new
as you are supposed to:解决方案是不要违背语言并按照您的预期使用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;
}
You could also use malloc
with placement new
, but that's only useful if you need memory without actual objects (eg in vector implementation).您也可以将malloc
与放置new
一起使用,但这仅在您需要没有实际对象的内存时才有用(例如在向量实现中)。
Note: it's a bad smell to use raw new
in modern C++ (well, 9 years old, but as modern as std::unordered_map
).注意:在现代 C++ 中使用 raw new
很糟糕(嗯,9 岁了,但和std::unordered_map
一样现代)。 Use smart pointers and STL containers instead.请改用智能指针和 STL 容器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.