大约"circular reference",我用了weak_ptr但仍然发生内存泄漏
About "circular reference", I used weak_ptr but memory leak still happened
我读到:
如何避免shared_ptr内存泄漏?
我知道我需要使用weak_ptr来避免循环引用。
所以我创建了一个小程序来播放循环引用。
将调用以下对象(spyder(
class spyder {
public:
spyder(std::string _name):
m_name(_name), finger(nullptr)
{ }
inline const std::string ask_name() const{
return m_name;
}
std::shared_ptr<spyder> finger;
private:
std::string m_name;
};
我在主代码中调用spyder并shared_ptr和weak_ptr:
int main(){
auto sA = std::make_shared<spyder>("A");
auto sB = std::make_shared<spyder>("B");
std::weak_ptr<spyder> wp_sA(sA);
std::weak_ptr<spyder> wp_sB(sB);
sA->finger = wp_sB.lock();
sB->finger = wp_sA.lock();
}
上面的代码发生了内存泄漏(使用 valgrind 进行检查(。
==20753== Memcheck, a memory error detector
==20753== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==20753== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==20753== Command: ./t
==20753==
==20753==
==20753== HEAP SUMMARY:
==20753== in use at exit: 128 bytes in 2 blocks
==20753== total heap usage: 3 allocs, 1 frees, 72,832 bytes allocated
==20753==
==20753== LEAK SUMMARY:
==20753== definitely lost: 64 bytes in 1 blocks
==20753== indirectly lost: 64 bytes in 1 blocks
==20753== possibly lost: 0 bytes in 0 blocks
==20753== still reachable: 0 bytes in 0 blocks
==20753== suppressed: 0 bytes in 0 blocks
==20753== Rerun with --leak-check=full to see details of leaked memory
==20753==
==20753== For counts of detected and suppressed errors, rerun with: -v
==20753== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
但是在我将上面的代码修改为:
int main(){
spyder sA("A"), sB("B");
std::weak_ptr<spyder> wp_sA( std::make_shared<spyder>("A") ) ;
std::weak_ptr<spyder> wp_sB( std::make_shared<spyder>("B") );
sA.finger = wp_sB.lock();
sB.finger = wp_sA.lock();
}
内存泄漏尚未发生,
==20695== Memcheck, a memory error detector
==20695== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==20695== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==20695== Command: ./t
==20695==
==20695==
==20695== HEAP SUMMARY:
==20695== in use at exit: 0 bytes in 0 blocks
==20695== total heap usage: 3 allocs, 3 frees, 72,832 bytes allocated
==20695==
==20695== All heap blocks were freed -- no leaks are possible
==20695==
==20695== For counts of detected and suppressed errors, rerun with: -v
==20695== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我对此感到困惑。
你根本没有解决循环依赖关系。
在您的第一个版本中,
sA
由shared_ptr
管理,并存储要sB
shared_ptr
。sB
又由shared_ptr
管理,并存储shared_ptr
sA
。这意味着它们的引用计数永远不会变为 0。
相反,finger
应该是类型std::weak_ptr
,并且您应该仅在需要使用它之前lock()
它。
class spyder {
public:
spyder(std::string _name):
m_name(_name), finger()
{ }
inline const std::string ask_name() const{
return m_name;
}
std::weak_ptr<spyder> finger;
private:
std::string m_name;
};
int main(){
auto sA = std::make_shared<spyder>("A");
auto sB = std::make_shared<spyder>("B");
sA->finger = sB;
sB->finger = sA;
}
您的第二个版本
从临时shared_ptr
构造weak_ptr
,这意味着在构造后立即weak_ptr
expired()
。sA.finger
和sB.finger
都在此版本中存储nullptr
(但没有内存泄漏(。
您的代码泄漏,因为它仍然具有循环引用。sA -> sA::finger -> sB -> sB::finger -> sA
std::weak_ptr
的要点是存储对指针的引用。为了避免内存泄漏,您的类源应如下所示:
class spyder {
public:
spyder(std::string _name):
m_name(_name), finger(nullptr)
{ }
inline const std::string ask_name() const{
return m_name;
}
std::weak_ptr<spyder> finger;
private:
std::string m_name;
};
相关文章:
- C++功能泄漏内存,我是C++新手,不确定如何解决
- 我的堆栈弹出式磁带的实现是否泄漏内存?
- 将 c++ 向量转换为字符 ** 而不会泄漏内存
- 析构函数 C++ 使泄漏内存
- 构造函数对象赋值是否泄漏内存
- corba :: orb_init泄漏内存
- Gmock泄漏内存
- 如何在不泄漏内存的情况下删除链接列表
- Visual C ODBC关闭记录集泄漏内存
- 为什么泄漏内存比在动态数组上执行 delete[] 慢
- OpenGL正在泄漏内存.哪个对象未释放
- 可以std ::退出泄漏内存
- uiautomation findall泄漏内存
- 为什么在此OpenCL代码中泄漏内存,为什么要泄漏内存
- pthread在完成后会泄漏内存
- win32 标准::线程泄漏内存
- 返回指向同一变量的指针是否会泄漏内存
- 使用clectType(new any_type())可能会泄漏内存泄漏
- Windows开发:如何确定我的应用程序是否正在泄漏内存
- WinHttp打开泄漏内存