C++ 容器对象作为(void*)传递时的共享指针行为
我在类对象(ObjA)中共享了_ptr变量。需要将此对象存储为另一类对象(ObjB)的(void*)实体 我的问题是,shared_ptr的行为会是什么(关联的堆内存会被释放吗?它的引用计数会发生什么变化?)-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
请帮助解决此内存泄漏。此处的
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