gpt4 book ai didi

c++ - 处理核心转储条件

转载 作者:行者123 更新时间:2023-11-30 01:02:27 25 4
gpt4 key购买 nike

我有一些简单的代码(这是我拥有的较大代码的一个小得多的示例):

#include <iostream>
#include <unordered_map>
#include <list>

// List of blocks
std::list<struct Block> Blocks;

class ObjInfo
{
private:
int size;
public:
ObjInfo(int size){this->size = size;}
int get_size() {return size;}
};

struct Block
{
// name of the block
int x;
// Actual variable stack
std::unordered_map <int, ObjInfo*> objinfostack;
};

int main()
{
int x = 2;
while( x >= 0 )
{
Block b;
b.x = x;
b.objinfostack.insert(std::make_pair(x, new ObjInfo(4)));
--x;
Blocks.push_front(b);
}
for(std::list<struct Block>::iterator i = Blocks.begin(); i!=Blocks.end(); ++i)
{
std::cout << "here: " << i->objinfostack[1]->get_size() << '\n';
}

return 0;

}

快速解释代码中发生的事情:

请注意以下行会导致 seg 错误:

std::cout << "here: " << i->objinfostack[1]->get_size() << '\n';

这是因为访问无效:

i->objinfostack[1]

因为我会在 Blocks 列表中得到这样的东西:

i->objinfostack[2], i->objinfostack[1]

我的问题是如何处理此类无效条件。

最佳答案

how can I handle such invalid condition

您可以通过不使用 operator [] 来处理此类情况对于 map ,如果您不确定该条目是否存在。 operator []如果键值不存在,将自动在映射中插入一个条目。您无法更改此行为——这就是 operator [] 的方式当 key 不存在时工作,因为它将创建一个 nullptr对于值,因为这是指针类型的零初始值。

相反,您应该使用 std::unordered_map::find()测试 key 是否存在而不是使用 [] , 如果不是 end() 则使用返回的迭代器:

auto iter = i->objinfostack.find(1);
if ( iter != i->objinfostack.end())
std::cout << "here: " << iter->second->get_size() << '\n';

如果你真的想在键不存在的情况下插入一个项目,并且你希望对象指向某个有效的地方,那么你需要显式调用insert()。 :

i->objinfostack.insert({1, new ObjInfo(4)});

将会发生的是,insert 总是检查键条目是否存在,如果不存在,则将一个新条目插入到映射中。因此,如果条目不存在,上面的代码将始终创建一个条目,如果条目已经存在,则将单独保留该条目。

然而,这样做的一个问题是,如果对象已经存在,则会发生内存泄漏,因为 new将在没有相应删除的情况下被调用。要解决此问题,您可以

1) 更改您的映射以将 RAII 类型存储为值类型(例如 std::vector<ObjInfo> std::shared_ptr、std::unique_ptr`),或

2) 检测到没有发生插入,因此 delete单独分配的对象。

auto new_ptr = new ObjInfo(4);
auto pr = i->objinfostack.insert({1, new_ptr});
if (!pr.second) // insert didn't happen
delete new_ptr;

但这当然很麻烦,可能最简单的方法是使用 std::map::find()首先,如果找不到该条目,则分配/插入到映射中。

所以选择你的——

1) 如果条目不存在,则什么也不做(使用 find())或

2) 如果该条目不存在,则创建一个具有有效 ObjInfo 的条目(使用 insert() ,但请注意上述警告)。


底线是永远不要使用 map operator []无条件,除非您确定要自动创建一个具有默认构造值或零初始化值的新 key 。

关于c++ - 处理核心转储条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56104666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com