C++ Boost共享指针和内存管理

C++ Boost共享指针和内存管理,c++,boost,memory-leaks,shared-ptr,C++,Boost,Memory Leaks,Shared Ptr,我最近才开始使用boost,它提供的功能和API给我留下了深刻的印象 在使用boost::shared_ptr时,当我使用Valgrind检查程序时,我发现大量“仍然可以访问”的内存泄漏。根据Valgrind的文件,这些都不是问题。但是,由于我只使用标准C++库,所以我总是确保编写的程序完全没有内存泄漏。p> 我的问题是,这些内存泄漏是否值得担心?我尝试使用reset(),但是它只减少引用计数,不释放内存。我可以安全地忽略这些,或者以任何方式强制释放boost::shared_ptr分配的内存吗

我最近才开始使用boost,它提供的功能和API给我留下了深刻的印象

在使用boost::shared_ptr时,当我使用Valgrind检查程序时,我发现大量“仍然可以访问”的内存泄漏。根据Valgrind的文件,这些都不是问题。但是,由于我只使用标准C++库,所以我总是确保编写的程序完全没有内存泄漏。p> 我的问题是,这些内存泄漏是否值得担心?我尝试使用reset(),但是它只减少引用计数,不释放内存。我可以安全地忽略这些,或者以任何方式强制释放boost::shared_ptr分配的内存吗

多谢各位

编辑1:

我在这段代码中使用apache thrift。使用valigrind进一步检查,使用选项--show reachable=yes,几乎所有泄漏消息如下所示:

==6813== 24 bytes in 1 blocks are still reachable in loss record 3 of 21
==6813==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6813==    by 0x5E7A783: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6813==    by 0x5EF524A: lh_insert (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6813==    by 0x5E7BC17: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6813==    by 0x5E7C268: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6813==    by 0x5BF43C5: SSL_CTX_free (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==6813==    by 0x4E9574F: apache::thrift::transport::SSLContext::~SSLContext() (TSSLSocket.cpp:71)
==6813==    by 0x4E95768: apache::thrift::transport::SSLContext::~SSLContext() (TSSLSocket.cpp:74)
==6813==    by 0x4E96C08:  apache::thrift::transport::TSSLSocketFactory::~TSSLSocketFactory() (sp_counted_base_gcc_x86.hpp:145)
==6813==    by 0x4E96C98: apache::thrift::transport::TSSLSocketFactory::~TSSLSocketFactory() (TSSLSocket.cpp:369)
==6813==    by 0x42A986: void boost::checked_delete<apache::thrift::transport::TSSLSocketFactory>(apache::thrift::transport::TSSLSocketFactory*) (checked_delete.hpp:34)
==6813==    by 0x42ADE3: boost::detail::sp_counted_impl_p<apache::thrift::transport::TSSLSocketFactory>::dispose() (sp_counted_impl.hpp:78)
==6813==1个块中的24个字节仍然可以在丢失记录3(共21个)中访问
==6813==at 0x4C2B6CD:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==6813==0x5E7A783:CRYPTO_malloc(在/lib/x86_64-linux-gnu/libcrypto.so.1.0.0中)
==6813==by 0x5EF524A:lh_insert(in/lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6813==0x5E7BC17:???(在/lib/x86_64-linux-gnu/libcrypto.so.1.0.0中)
==6813==0x5E7C268:???(在/lib/x86_64-linux-gnu/libcrypto.so.1.0.0中)
==6813==by 0x5BF43C5:SSL_CTX_free(在/lib/x86_64-linux-gnu/libssl.so.1.0.0中)
==6813==by 0x4E9574F:apache::thrift::transport::SSLContext::~SSLContext()(TSSLSocket.cpp:71)
==6813==by 0x4E95768:apache::thrift::transport::SSLContext::~SSLContext()(TSSLSocket.cpp:74)
==6813==by 0x4E96C08:apache::thrift::transport::TSSLSocketFactory::~TSSLSocketFactory()(sp_counted_base_gcc_x86.hpp:145)
==6813==by 0x4E96C98:apache::thrift::transport::TSSLSocketFactory::~TSSLSocketFactory()(TSSLSocket.cpp:369)
==6813==by 0x42A986:void boost::checked_delete(apache::thrift::transport::TSSLSocketFactory*)(checked_delete.hpp:34)
==6813==by 0x42ADE3:boost::detail::sp_counted_impl_p::dispose()(sp_counted_impl.hpp:78)
这是否意味着是节俭代码泄漏内存

谢谢。

看看

如果程序开始时的
uORDBLK
与程序结束时的相同,则没有泄漏。因为您已成功释放了所有分配的内存。

请查看


如果程序开始时的
uORDBLK
与程序结束时的相同,则没有泄漏。由于您已成功释放了分配的所有内存。

通常,如果内存仍然可以访问,则不会泄漏。如果将泄漏定义为使用malloc/new保留的一些内存,但不能再释放它,如中所示

//this leaks since p is unreachable outside the scope
int main() {
  char * p = (char*)malloc(10);
  return 0; 
}
你可能会遇到这样一种情况:你的记忆总是在增长,但从技术上讲,它不是一个漏洞,例如,你有一个全局列表,你总是把东西放进去,但从不把它们放出去。 在这种情况下,列表内存是可访问的,您可以
释放它

话虽如此,根据问题中粘贴的调用堆栈,引用的内存似乎是libcrypto在销毁thrift SSL传输时进行的一些分配


因此,共享指针不是问题所在,很可能只是libcrypto内部使用的缓冲内存。

通常,如果内存仍然可以访问,则不会泄漏。如果将泄漏定义为使用malloc/new保留的一些内存,但不能再释放它,如中所示

//this leaks since p is unreachable outside the scope
int main() {
  char * p = (char*)malloc(10);
  return 0; 
}
你可能会遇到这样一种情况:你的记忆总是在增长,但从技术上讲,它不是一个漏洞,例如,你有一个全局列表,你总是把东西放进去,但从不把它们放出去。 在这种情况下,列表内存是可访问的,您可以
释放它

话虽如此,根据问题中粘贴的调用堆栈,引用的内存似乎是libcrypto在销毁thrift SSL传输时进行的一些分配


因此,您的共享指针不是问题所在,很可能只是libcrypto内部使用的缓冲内存。

您能否提供一个最小的可编译示例来演示泄漏?通常
共享\u ptr
托管内存在引用计数变为零时被释放。如果不是这样,则可能有各种原因,具体取决于应用程序如何使用
共享\u ptr
。最糟糕的是,在类结构中可能会有带有共享指针的循环引用,在这种情况下,分配的内存将永远不会被释放;找到解决方案的关键是
弱\u ptr
@fredrarson:谢谢你的建议。我将尝试发布一个可编译的示例,但很难在示例中获得相同的场景。您能否提供一个演示泄漏的最小可编译示例?通常
共享\u ptr
托管内存在引用计数变为零时被释放。如果不是这样,则可能有各种原因,具体取决于应用程序如何使用
共享\u ptr
。最糟糕的是,在类结构中可能会有带有共享指针的循环引用,在这种情况下,分配的内存将永远不会被释放;找到解决方案的关键是
弱\u ptr
@fredrarson:谢谢你的建议。我将尝试发布一个可编译的示例,但很难在示例中获得相同的场景。有趣。从
atexit()
处理程序调用
mallinfo()
合法吗?很有趣。从
atexit()
处理程序调用
mallinfo()
是否合法?+1。当我追溯到泄漏的源头时,它们来自我正在使用的库。+1。当我追溯到泄漏的源头时,它们来自我正在使用的库。