循环迭代后共享指针断言失败

shared pointer assertion fail after iteration in a loop

本文关键字:断言 失败 指针 共享 迭代 循环      更新时间:2023-10-16

我是 boost shared_ptr的新手,正在考虑迭代我的集合以获得最佳对象。编辑:添加了有关first_world的信息

std::set<World::CPtr> first_world = ... // long call, but it gets a set of constant shared pointers to the class World, where various methods exist
   typedef boost::shared_ptr<World const> CPtr;
   World::CPtr best = *(first_world.begin());
   for (World::CPtr lo : first_world) {
     if (best->getValue() >= lo->getValue() ){
       best = lo;
     }
   }

稍后我想使用该共享指针,我的程序崩溃,并传达断言"px != 0"失败。我遵循了这里的规则,我的意思是我在循环中使用共享指针作为迭代器,但随后我将其分配给另一个指针。这是不好的做法,有更好的做法吗?

cout << "name is: " << best->getDefinition() << endl;

粘贴在那里的内容没有任何明显的错误,因此在创建集合的长调用中可能会出现错误。

例如,如果在向集合中添加元素时涉及原始指针,则很容易搞砸这一点。考虑这种情况,这是最佳实践链接中提到的常见错误的具体说明:

std::set<World::CPtr> first_world;
World* pWorld = new World();
// Bad:
first_world.insert(World::CPtr(pWorld));
first_world.insert(World::CPtr(pWorld));
// Oops!! You now have two independently refcounted entries in first_world!
// emplace is just as deadly, but more subtle.
// Now you'll have three shared pointers in your set:
first_world.emplace(pWorld);

如果您查看first_world中的条目并看到重复项,那么您就会知道自己遇到了麻烦。为避免此类错误,请确保仅从其他shared_ptrs(或boost::make_shared(构造shared_ptrs。

所以这就是提示#1:避免从原始指针构造shared_ptrs。(这包括this指针,如果世界将自己添加到你的集合中......如果你这样做,最好开始谷歌搜索enable_shared_from_this(。

现在,让我们遵循该准则来获取预期行为:

std::set<World::CPtr> first_world;
World::CPtr spWorld1 = boost::make_shared<World>();
World::CPtr spWorld2{spWorld1};
first_world.insert(spWorld1);
first_world.insert(spWorld2);
// Just one element in first_world now, as expected.

最后,一些(有些不相关的(建议:

  • std::set正如您声明的那样,它在比较条目时仅查看堆上 World 对象的地址。因此,如果你在堆上有两个逻辑上相同的不同世界,那么它们在集合中都有不同的条目。这是你的意图吗?如果你想避免逻辑重复,你需要插入你自己的自定义比较函数(std::set 的第二个模板参数(来对世界进行深入比较。
  • 在查找最大值之前检查以确保first_world不为空,否则会发生不好的事情。
  • 标准算法是您的朋友!请考虑使用 std::max_element 算法而不是原始循环。(这使得其他人更容易通过快速浏览来推理你在做什么(。