共享指针段错误——如何正确共享PlanningScene实例?
Alright, let's break this down based on the details you've given about the PlanningScene class. There are two main scenarios to consider here—whether you want SceneStuff to share the same instance of the planning scene, or work with its own independent copy.
Since ps_ptr is a boost::shared_ptr<PlanningScene>, the simplest and safest way to share the same instance with SceneStuff is to pass the shared pointer directly. Shared pointers are designed for shared ownership, so passing them (either by value or const reference) will correctly manage the reference count to avoid memory leaks or double-frees.
Example: Passing to SceneStuff via Constructor
class SceneStuff { public: // Accept the shared_ptr by value (increments reference count) SceneStuff(boost::shared_ptr<PlanningScene> scene_ptr) : scene_ptr_(std::move(scene_ptr)) {} // Use move semantics to avoid unnecessary copies // Or accept by const reference if you don't need to transfer ownership // SceneStuff(const boost::shared_ptr<PlanningScene>& scene_ptr) // : scene_ptr_(scene_ptr) {} private: boost::shared_ptr<PlanningScene> scene_ptr_; // Holds shared ownership }; // Usage auto ps_ptr = boost::make_shared<PlanningScene>(); auto my_scene_stuff = boost::make_shared<SceneStuff>(ps_ptr);
Critical Note for enable_shared_from_this
If you need to pass the PlanningScene instance from within one of its own member functions to SceneStuff, never do this:
// BAD: Creates a new shared_ptr that doesn't track the existing reference count auto bad_ptr = boost::shared_ptr<PlanningScene>(this);
Instead, use shared_from_this() (provided by std::enable_shared_from_this<PlanningScene>):
// GOOD: Returns a shared_ptr tied to the existing ownership chain auto good_ptr = this->shared_from_this(); auto my_scene_stuff = boost::make_shared<SceneStuff>(good_ptr);
This ensures the reference count is updated correctly, preventing double-frees or dangling pointers.
If SceneStuff needs its own separate version of the planning scene (so changes to one don't affect the other), use the clone() method provided by PlanningScene. The class's boost::noncopyable inheritance means you can't just copy the instance directly—clone() is the intended way to create a duplicate.
Example: Using clone()
Assuming the PlanningScene's clone() method is implemented to return a new shared pointer to a copied instance:
// Inside PlanningScene class declaration class PlanningScene : private boost::noncopyable, public std::enable_shared_from_this<PlanningScene> { public: // Clone returns a shared_ptr to a new, independent instance boost::shared_ptr<PlanningScene> clone() const { // Internal implementation copies all scene data to a new instance return boost::make_shared<PlanningScene>(*this); // Note: This requires a private copy constructor, since the class is noncopyable publicly } // ... other members ... }; // Usage: Pass a copy to SceneStuff auto ps_ptr = boost::make_shared<PlanningScene>(); auto scene_copy = ps_ptr->clone(); auto my_scene_stuff = boost::make_shared<SceneStuff>(scene_copy);
Now my_scene_stuff works with its own independent planning scene, separate from the original ps_ptr.
- Never pass raw pointers: Don't extract the raw pointer with
ps_ptr.get()and pass that toSceneStuff. This bypasses the shared ownership management and risks dangling pointers or double-frees. - Watch for cyclic references: If
SceneStuffholds ashared_ptr<PlanningScene>andPlanningScenealso holds ashared_ptr<SceneStuff>, you'll create a cyclic reference that prevents both objects from being destroyed. Useboost::weak_ptrfor one side of the relationship to break the cycle. - Respect
noncopyable: Don't try to create copies ofPlanningSceneviaPlanningScene copy = *ps_ptr;—this is explicitly blocked byboost::noncopyable. Always useclone()when you need a duplicate.
内容的提问来源于stack exchange,提问作者BoltzmannBrain

