
voID MyClass::onopenModalBtnClicked(){ uiManager->load(L"data/ui/testmodal.Json"); std::shared_ptr<UIElement> modal = uiManager->getElementByID("loginModal"); if(modal) { modal->getElementByID("closebutton")->onClicked = [modal]() { modal->hIDe(); }; }} 这个工作正常,当点击按钮时,模态是关闭的,onClicked是一个std ::函数.
我也在我的应用程序的开头有这个:
#if defined(DEBUG) | defined (_DEBUG) _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);#endif
使用上面的代码,我会收到很多内存泄漏,如果我将代码更改为下面的代码,它们都会消失:
voID MyClass::onopenModalBtnClicked(){ uiManager->load(L"data/ui/testmodal.Json"); std::shared_ptr<UIElement> modal = uiManager->getElementByID("loginModal"); if(modal) { modal->getElementByID("closebutton")->onClicked = [this]() { uiManager->getElementByID("loginModal")->hIDe(); }; }} 我假设传递shared_ptr通过值将引用计数增加1,然后该引用永远不会超出范围,或者在报告了mem泄漏之后超出范围.所以我试图在我使用shared_ptr之后调用lambda里面的reset,但是我得到这个编译器的错误:
错误1错误C2662:’voID std :: shared_ptr< _Ty> :: reset(voID)throw()’:不能将’this’指针从’const std :: shared_ptr< _Ty>到'std :: shared_ptr< _Ty> &安培;”
所以问题是如何使用捕获的模态,而不是得到那些内存泄漏?
编辑:
所以我通过向lambda添加mutable来摆脱编译错误.
if(modal){ modal->getElementByID("closebutton")->onClicked = [modal]() mutable { modal->hIDe(); modal.reset(); };} 现在如果我点击关闭按钮,并关闭应用程序没有内存泄漏,因为重置清理该引用.但如果按钮从未点击,我仍然会收到泄漏.
解决方法 您已经创建了一个shared_ptr循环.在引用计数命中0之前,模态不能被破坏.然后,将shared_ptr的副本传递给模态到labmda函数中,增加其引用计数.然后,您将该lambda函数分配给模态的成员.
这意味着模态总是由其回调函数引用.但是,它的回调函数在modal没有refcount之前不能被销毁. Modal最终以1的ref计数卡住.
通常的解决方案是将一个裸指针或(最好是)一个弱指针传给lambda
总结以上是内存溢出为你收集整理的c – 通过值将shared_ptr传递给lambda泄漏内存全部内容,希望文章能够帮你解决c – 通过值将shared_ptr传递给lambda泄漏内存所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)