Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 容器对象作为(void*)传递时的共享指针行为_C++_C++11_Memory Management_Shared Ptr_Void Pointers - Fatal编程技术网

C++ 容器对象作为(void*)传递时的共享指针行为

C++ 容器对象作为(void*)传递时的共享指针行为,c++,c++11,memory-management,shared-ptr,void-pointers,C++,C++11,Memory Management,Shared Ptr,Void Pointers,我在类对象(ObjA)中共享了_ptr变量。需要将此对象存储为另一类对象(ObjB)的(void*)实体 我的问题是,shared_ptr的行为会是什么(关联的堆内存会被释放吗?它的引用计数会发生什么变化?)- 当ObjA转换为void时* 当ObjB的void*实体被转换回(ClassA*)时 简化代码: 但这是一个错误,因为AA类中的shared_ptr变量不允许显式删除-它仅在超出范围时释放其分配的区域。(在这种情况下,它永远不知道何时超出范围!) 另外,类BB是第三方类-我不能修改smp

我在类对象(ObjA)中共享了_ptr变量。需要将此对象存储为另一类对象(ObjB)的(void*)实体

我的问题是,shared_ptr的行为会是什么(关联的堆内存会被释放吗?它的引用计数会发生什么变化?)-

  • 当ObjA转换为void时*

  • 当ObjB的void*实体被转换回(ClassA*)时

  • 简化代码:

    但这是一个错误,因为AA类中的shared_ptr变量不允许显式删除-它仅在超出范围时释放其分配的区域。(在这种情况下,它永远不知道何时超出范围!)

    另外,类BB是第三方类-我不能修改smpl成员变量的void*类型(_userData变量在节点类中,在Cocos2dx中)。
    请帮助解决此内存泄漏。

    此处的
    void*
    充当观察指针。它根本不影响共享指针,因为共享指针甚至不知道指向其包含对象的原始指针是否存在

    如果您选择一个
    shared\u ptr
    而不是原始指针(并通过原始共享指针构造它,例如,您的setter应该被
    void setter(std::shared\u ptr const&p)
    替换),则情况会有所不同

    在这种情况下,参考计数受到影响,并且将确保指向的对象的生存。关于此选项,请参阅


    编辑:从您的评论来看,您似乎在寻找类似以下内容的设置:

    struct AA
    {
        //...
    };
    
    
    struct BB
    {
        std::shared_ptr<void> smpl;
    
        void setter(std::shared_ptr<void> const& p)
        {
            smpl = p;  //now the ref count of your shared_tr to AA is increased
        }
    };
    
    int main()
    {    
        auto objA = std::make_shared<AA>();
        auto objB = std::make_shared<BB>();
    
        objB->setter(objA);
    
        std::cout<<objA.use_count()<<std::endl;   //prints "2"
    }
    
    AA
    内的共享指针完全不受影响

    //some code later
    AA *objA_2 = (AA*)objB->getter();
    //status of allocated int in class AA here?
    
    同样,共享指针不受影响。然而,这一步需要小心:如果原始对象不再是活动的,您将得到一个悬空的指针。因此,最好使用共享指针

    shared_ptr<int> p2 = objA_2->get_aptr();
    //is this allowed
    
    shared_ptr p2=objA_2->get_aptr();
    //这允许吗
    
    当然,如果指针是有效的


    我不明白的一点是,为什么在类内部使用智能指针,而在类外部使用原始指针。有什么原因吗?

    共享ptr的生存期会忽略无效状态:如果源ptr死亡,则资源将被释放。如果您对同一资源进行第二次共享ptr(而不是通过共享ptr复制ctor),他们都会认为自己拥有该资源,并且会导致双重删除(错误)。此外,这告诉了您有关强制转换部分的大部分信息。@Yakk-您是说两个共享ptr指向同一位置而不增加引用计数吗。不确定这是否可行。@davidhigh-感谢您的链接,了解了在使用void*时static_cast的可用性。虽然还不确定这是否能回答我当前的问题。@approve:cast与指针无关。但是在使用
    void*
    之类的工具时,知道这一点很好,不是吗;-)“此处的void*充当一个观察指针。它根本不会影响共享指针,因为共享指针甚至不知道指向其包含对象的原始指针是否存在。”没错,这是我的担心-我们不能删除void*变量,并且封闭的共享\u ptr永远不会超出范围。这会导致巨大的内存泄漏。如果我是,请更正wrong@Apporve:是的,这是这种设计选择的缺点。改用共享的ptr。它将正确地销毁您的对象。我将做一个编辑,以便更清楚地显示出来。@davidhigh:精彩的解释,非常有助于理解。但这并不能解决我的问题——我使用的是第三方库,这迫使我使用void*类变量及其getter setter(setUserData,getUserData for Node class,在cocos2dx中)。这会导致内存泄漏。请你提出一些建议,在不改变给定条件的情况下避免使用它(只使用原始void*而不是共享。\u ptr)。@davidhigh:无论如何,谢谢你的解释,我从来都不知道共享指针也可以用于void*。虽然不是void*的粉丝,但当你被迫说:)@approve:当你说出你想做什么时,我会尽力帮你。问题:(i)原始问题中的示例显示没有问题,即没有内存泄漏(--至少如果您在
    objA
    objB
    上正确调用
    delete
    )。你能编辑它来澄清你的问题吗?(ii)调用
    AA
    的析构函数时,删除
    AA
    中的共享指针。那么您的问题似乎是
    AA
    的生命周期,而不是内部共享指针的生命周期?您可以使用
    shared\u ptr吗。
    
    objB->setter(objA);
    //status of allocated int in class AA here?
    
    //some code later
    AA *objA_2 = (AA*)objB->getter();
    //status of allocated int in class AA here?
    
    shared_ptr<int> p2 = objA_2->get_aptr();
    //is this allowed