如何解决C ++ unordered_map初始化读取访问冲突
我有一个结构:
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;
}
我收到以下消息:“抛出异常:读取访问冲突。_Pnext为0xCDCDCDD1。”构造unordered_map时引发的异常。我知道MVS用0xCD填充堆分配的内存,这就是_Pnext指针具有此值的原因,但是我不明白为什么unordered_map构造函数没有将这些字段归零。
我意识到现代C ++的实现方法是使用new / constructors,但是我试图以非OOP的方式(基本上)使用POD对象来编写此代码。
我初始化地图不正确吗?
解决方法
malloc的C调用
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 ++中使用原始的new
是不好的气味(已经9岁了,但与std::unordered_map
一样现代)。改用smart pointers和STL容器。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。