Boost 翻译内存泄漏(版本 1.65.1)

问题描述 投票:0回答:1

我尝试用 valgrind 分析这样一个简单的程序

int main(int argc, char **argv) {

    generator gen;
    gen.add_messages_path(".");
    gen.add_messages_domain("hello");

    locale::global(gen("de_DE.UTF-8"));
    cout.imbue(locale());

    cout << translate("Hello World") << endl;
}

它返回问题列表:

LEAK SUMMARY:
==8895==    definitely lost: 0 bytes in 0 blocks
==8895==    indirectly lost: 0 bytes in 0 blocks
==8895==      possibly lost: 1,376 bytes in 4 blocks
==8895==    still reachable: 67,954 bytes in 253 blocks
==8895==                       of which reachable via heuristic:
==8895==                         newarray           : 14,440 bytes in 29 blocks

为什么会发生这种情况?如何在退出程序之前清除内存?

保持帖子简短的问题之一:

==8895== 1,376 bytes in 4 blocks are possibly lost in loss record 202 of 212
==8895==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8895==    by 0x643D6B6: icu_60::UnicodeString::allocate(int) (in /usr/lib/x86_64-linux-gnu/libicuuc.so.60.2)
==8895==    by 0x643F3A8: icu_60::UnicodeString::cloneArrayIfNeeded(int, int, signed char, int**, signed char) (in /usr/lib/x86_64-linux-gnu/libicuuc.so.60.2)
==8895==    by 0x643F940: icu_60::UnicodeString::doAppend(char16_t const*, int, int) (in /usr/lib/x86_64-linux-gnu/libicuuc.so.60.2)
==8895==    by 0x64AD66D: icu_60::SimpleFormatter::format(char16_t const*, int, icu_60::UnicodeString const* const*, icu_60::UnicodeString&, icu_60::UnicodeString const*, signed char, int*, int, UErrorCode&) (in /usr/lib/x86_64-linux-gnu/libicuuc.so.60.2)
==8895==    by 0x64AD83B: icu_60::SimpleFormatter::formatAndAppend(icu_60::UnicodeString const* const*, int, icu_60::UnicodeString&, int*, int, UErrorCode&) const (in /usr/lib/x86_64-linux-gnu/libicuuc.so.60.2)
==8895==    by 0x64AD915: icu_60::SimpleFormatter::format(icu_60::UnicodeString const&, icu_60::UnicodeString const&, icu_60::UnicodeString&, UErrorCode&) const (in /usr/lib/x86_64-linux-gnu/libicuuc.so.60.2)
==8895==    by 0x5FD629E: icu_60::SimpleDateFormat::construct(icu_60::DateFormat::EStyle, icu_60::DateFormat::EStyle, icu_60::Locale const&, UErrorCode&) (in /usr/lib/x86_64-linux-gnu/libicui18n.so.60.2)
==8895==    by 0x5FD700D: icu_60::SimpleDateFormat::SimpleDateFormat(icu_60::DateFormat::EStyle, icu_60::DateFormat::EStyle, icu_60::Locale const&, UErrorCode&) (in /usr/lib/x86_64-linux-gnu/libicui18n.so.60.2)
==8895==    by 0x5FD05C9: icu_60::DateFormat::create(icu_60::DateFormat::EStyle, icu_60::DateFormat::EStyle, icu_60::Locale const&) (in /usr/lib/x86_64-linux-gnu/libicui18n.so.60.2)
==8895==    by 0x4EE389B: boost::locale::impl_icu::icu_formatters_cache::icu_formatters_cache(icu_60::Locale const&) (in /usr/lib/x86_64-linux-gnu/libboost_locale.so.1.65.1)
==8895==    by 0x4EE3B47: std::locale boost::locale::impl_icu::install_formatting_facets<char>(std::locale const&, boost::locale::impl_icu::cdata const&) (in /usr/lib/x86_64-linux-gnu/libboost_locale.so.1.65.1)
==8895== 
==8895== 1,904 bytes in 1 blocks are still reachable in loss record 203 of 212
==8895==    at 0x4C3217F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8895==    by 0x4EE3B39: std::locale boost::locale::impl_icu::install_formatting_facets<char>(std::locale const&, boost::locale::impl_icu::cdata const&) (in /usr/lib/x86_64-linux-gnu/libboost_locale.so.1.65.1)
==8895==    by 0x4ED3FCC: boost::locale::impl_icu::create_formatting(std::locale const&, boost::locale::impl_icu::cdata const&, unsigned int) (in /usr/lib/x86_64-linux-gnu/libboost_locale.so.1.65.1)
==8895==    by 0x4ED3504: boost::locale::impl_icu::icu_localization_backend::install(std::locale const&, unsigned int, unsigned int) (in /usr/lib/x86_64-linux-gnu/libboost_locale.so.1.65.1)
==8895==    by 0x4E988E8: boost::locale::localization_backend_manager::impl::actual_backend::install(std::locale const&, unsigned int, unsigned int) (in /usr/lib/x86_64-linux-gnu/libboost_locale.so.1.65.1)
==8895==    by 0x4E9482B: boost::locale::generator::generate(std::locale const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (in /usr/lib/x86_64-linux-gnu/libboost_locale.so.1.65.1)
==8895==    by 0x4E95006: boost::locale::generator::generate(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (in /usr/lib/x86_64-linux-gnu/libboost_locale.so.1.65.1)
==8895==    by 0x109E01: boost::locale::generator::operator()(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (in a.out)

我希望程序退出时有清晰的记忆

c++ boost valgrind translate
1个回答
0
投票

全局/静态的清理通常存在问题——编译器无法知道某些东西是否仍然可以使用。

因此,使用全局/静态有时会使用包装器来击败自动清理,如下所示:

Foo& Foo::get()
{
   static Foo& instance=*new Foo();
   return instance;
}

这样,您的实例将永远不会被删除。这也不是内存泄漏。

很可能这就是您所看到的。

为什么需要这个?在清理期间,即使编译器已将其删除,某些东西仍可能正在使用该 Foo 实例。虽然您可以尝试使用

shared_ptr
或类似的东西来解决这个问题,但您只是让事情变得比需要的更复杂:一旦进程终止,Foo 实例就消失了。

我还对持久线程做了类似的事情——也就是说,线程被启动,然后在程序的整个生命周期中一直存在。我没有给它们添加“退出”程序;无论如何,当程序退出时,它们都会死。

© www.soinside.com 2019 - 2024. All rights reserved.