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