当前位置: 首页 > 知识库问答 >
问题:

C++unordered_map初始化读取访问冲突

单于骁
2023-03-14

我有一个结构:

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++实现这一点的方式是使用新的/构造函数,但我试图用(基本上)POD对象以非OOP过程方式编写这段代码。

我是否错误地初始化了映射?

共有3个答案

上官霄
2023-03-14

malloc()不创建任何对象。它只是保留一些未初始化的内存。内存中没有对象,必须使用位置new创建这些对象。

现在,operator=需要一个现有对象,因为它是一个成员函数(总是)。通过在foo->info=std::unordered_map () 行调用这个运算符,可以在不存在的对象上调用运算符。

解决办法是不要违背语言,并按照您应该使用的方式使用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一起使用,但这仅在不需要实际对象的内存时才有用(例如,在vector实现中)。

注意:在现代C++中使用原始的new是一种难闻的气味(嗯,9年了,但是和std::unordered_map一样现代)。改用智能指针和STL容器。

汝才良
2023-03-14

对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();
慕容康安
2023-03-14

malloc()不初始化分配的内存,这在分配具有非平凡构造函数的对象时是很糟糕的。

您应该改用new

Foo* foo = new Foo;

若要释放通过new分配的对象,可以使用delete

delete pointe_to_object;
 类似资料:
  • 问题:给定一个字符串数组,将字母表组合在一起。你可以按任何顺序返回答案。 字形是一个单词或短语,通过重新排列一个不同的单词或短语的字母,通常使用所有的原始字母一次。 代码: 错误:

  • c++中有列表初始化的操作,类似这样: 同时vector也可以这样写: 在网上查阅资料,列表初始化(写法1)用于聚合类,聚合类不能有构造函数。 而写法2应该是调用了vector类的构造函数,那么意味着vector应改该不能使用列表初始化,这是不是矛盾了呢?

  • 我试图为Dropwizard创建一个调度作业,该作业每分钟运行一次,并查询数据库中的值。 为此,我需要在< code>initialize()阶段注册一些Dao和一个服务,如下所示: JDBI需要Dropw的和配置对象。 是否可以在这个阶段访问这些,以便正确设置我的依赖项?

  • 必需的初始值设定项的访问控制规则似乎与未指定必需的规则不同。为什么?

  • 在 Swift 3 中,dispatch_once函数被删除,迁移指南建议使用初始化闭包: 让myGlobal = { … global包含对闭包调用的初始化…}() _ = myGlobal //使用myGlobal只会在首次使用时调用初始化代码。 我想从初始化闭包中访问“Self”实例变量,如下所示: 为什么“自我”在闭包中是不可接近的,如何才能使它成为现实?

  • 本文向大家介绍C++ 数组初始化,包括了C++ 数组初始化的使用技巧和注意事项,需要的朋友参考一下 示例 数组只是特定类型变量的顺序存储位置的块。数组的分配方式与普通变量相同,但是在其名称后附加方括号,方括号[]中包含适合数组内存的元素数。 下面的数组示例使用typ int,变量名arrayOfInts和[5]数组可以容纳的元素数: 可以像这样同时声明和初始化数组 通过列出其所有成员来初始化数组时

  • 问题内容: 我在我的应用程序中使用ArrayList。 我想知道从Singleton类初始化ArrayList的确切过程。 该数据将在其他一些活动中使用。 有人可以帮助了解Singleton课堂吗? 问题答案: 这是创建单例类的方法: 任何需要调用arrayList的地方都可以: 要将元素添加到数组,请使用: 要么

  • 读取未初始化的变量会导致未定义的行为,例如 有人能给这个事实一个正式的解释吗?