簡體   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