在循环迭代后共享指针断言失败 [英] shared pointer assertion fail after iteration in a loop

查看:109
本文介绍了在循环迭代后共享指针断言失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来从boost shared_ptr的,并正在考虑遍历我设置,以获得最佳对象。
修改:关于增加信息first_world

 的std ::设为<世界:: CPTR> first_world = ... //长调用,但它得到了一组不断共享指针到类的世界里,各种方法存在   TYPEDEF提高:: shared_ptr的<世界常量> CPTR;
   世界:: CPTR最好= *(first_world.begin());
   对于(世界:: CPTR罗:first_world){
     如果(BEST->的getValue()&GT =某一地址>的getValue()){
       最好= LO;
     }
   }

后来我想使用共享指针,我的程序与传达断言`PX崩溃!= 0失败。我跟着从 的,我的意思是我用了一个共享指针在一个循环迭代但后来我把它分配给另一个指针。是不好的做法,有没有更好的做法?

  COUT<< 名字是:<< BEST-> getDefinition方法()&所述;&下; ENDL;


解决方案

没有在什么粘贴有公然错的,所以有可能会是在创建该集的长调用错误的。

例如,它会很容易搞砸了,如果将元素添加到集时原始指针都参与其中。考虑这种情况,一个常见的​​错误,在您的最佳实践环节几分提到的具体的例子:

 的std ::设为<世界:: CPTR> first_world;世界* pWorld =新的世界();//错误:
first_world.insert(世界:: CPTR(pWorld));
first_world.insert(世界:: CPTR(pWorld));//哎呀!你现在有first_world两个独立的引用计数项!//布设是一样致命,但更为微妙。
//现在,你必须在你的一套三共享指针:
first_world.emplace(pWorld);

如果您通过条目查看 first_world ,看看重复,那么你就会知道,你就麻烦了。为了避免这样的错误,请确保您只能从其他shared_ptrs构建shared_ptrs(或的boost :: make_shared )。

这就是提示#1:避免从原始指针构建 shared_ptrs 的。 (这包括如果世界要添加自己的一套...如果你这样做,这指针最好开始使用Google enable_shared_from_this )。

现在让我们遵循的准则来获得预期的行为:

 的std ::设为<世界:: CPTR> first_world;世界:: CPTR spWorld1 =的boost :: make_shared<&世界GT;();
世界:: CPTR spWorld2 {spWorld1};first_world.insert(spWorld1);
first_world.insert(spWorld2);
//在first_world只有一个元素现在,符合市场预期。

最后,几个(有点不相关的)建议:


  • 的std ::设置因为你已经宣布它只是望着堆在世界的地址的对象,在比较的条目。所以,如果你有一个在逻辑上是相同的,则他们就都有了组不同的条目堆上两个不同的世界。那是你的意图是什么?如果你想避免重复的逻辑,你就需要在自己的自定义比较函数(的std ::集的第二个模板参数)插做世界的深刻对比。

  • 检查以确保 first_world 不为空之前寻找最大的,否则不好的事情会发生。

  • 标准算法是你的朋友!请考虑使用 的std :: max_element 算法来代替原始循环。 (这使得它更容易为其他人来思考你和一个快速浏览做什么)。

I am new to shared_ptr from boost and am considering to iterate over my set to get the best object. EDIT: added information about 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;
     }
   }

Later I want to use that shared pointer, My program crashes with communicate that Assertion `px != 0' failed. I followed the rules from here, I mean I used a shared pointer as iterator in a loop but then I assign it to another pointer. Is that bad practice, is there better practice?

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

解决方案

Nothing's blatantly wrong in what's pasted there, so there's probably going to be a mistake in the long call that creates the set.

For example, it would be easy to mess this up if raw pointers are involved when adding elements to the set. Consider this situation, a concrete illustration of a common mistake that's sort of alluded to in your Best Practices link:

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);

If you look through your entries in first_world and see duplicates then you'll know you're in trouble. To avoid mistakes like this, make sure you only construct shared_ptrs from other shared_ptrs (or boost::make_shared).

So that's tip #1: Avoid constructing shared_ptrs from a raw pointers. (That includes the this pointer if Worlds are adding themselves to your set... if you're doing that, better start googling enable_shared_from_this).

Now let's follow that guideline to get expected behavior:

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.

Finally, a few (somewhat unrelated) suggestions:

  • std::set as you've declared it is only looking at the address of World objects on the heap when it compares entries. So if you have two different Worlds on the heap that are logically identical then they'll both have distinct entries in the set. Is that your intent? You'll need to plug in your own custom compare function (std::set's second template argument) to do a deep comparison of Worlds if you want to avoid logical duplicates.
  • Check to make sure that first_world isn't empty before looking for the max, otherwise bad things will happen.
  • Standard algorithms are your friend! Consider using the std::max_element algorithm instead of a raw loop. (This makes it easier for other people to reason about what you're doing with a quick glance).

这篇关于在循环迭代后共享指针断言失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆