【发布时间】:2019-09-09 10:10:12
【问题描述】:
我读到了:
How to avoid memory leak with 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;
};
我在主代码中使用 shared_ptr 和 weak_ptr 调用 spyder:
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)
我对此感到困惑。
【问题讨论】:
-
lock调用之后会发生什么?你曾经解锁过弱指针吗?请尝试创建一个minimal reproducible example 向我们展示,并从该示例中复制粘贴 Valgrind 的完整输出。 -
另外我认为你误解了一些东西,在第一个例子中你真正在做的是等于
sA->finger = sB; sB->finger = sA;。您需要将finger成员设为std::weak_ptr。 -
嗨@Someprogrammerdude:我已经更新了 Valgrind 的输出。命令是
valgrind --leak-check=summary ./t.out -
您无法修复具有弱引用的循环参考设计问题。
标签: c++ shared-ptr smart-pointers circular-reference weak-ptr