设置全局区域设置时内存泄漏

时间:2015-12-03 12:52:44

标签: c++ memory-leaks locale valgrind

我正在使用此代码设置我的语言环境:

locale::global(locale("pt_BR.UTF-8"));

我这样做是否正确?当我用Valgrind运行代码时,它显示内存泄漏。我该怎么处理? 我应该重置旧的语言环境吗?

376 bytes in 1 blocks are still reachable in loss record 65 of 73
==7536==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7536==    by 0x5380664: duplocale (duplocale.c:53)
==7536==    by 0x4EA436F: std::ctype<wchar_t>::ctype(__locale_struct*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA86B3: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA8BDA: std::locale::locale(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x40D68D: Relatorio::geraRelatorios() (Relatorio.cpp:23)
==7536==    by 0x402335: main (main.cpp:24)
==7536== 
==7536== 376 bytes in 1 blocks are still reachable in loss record 66 of 73
==7536==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7536==    by 0x5380664: duplocale (duplocale.c:53)
==7536==    by 0x4EA16DF: std::codecvt<wchar_t, char, __mbstate_t>::codecvt(__locale_struct*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA86E1: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA8BDA: std::locale::locale(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x40D68D: Relatorio::geraRelatorios() (Relatorio.cpp:23)
==7536==    by 0x402335: main (main.cpp:24)
==7536== 
==7536== 376 bytes in 1 blocks are still reachable in loss record 67 of 73
==7536==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7536==    by 0x5380664: duplocale (duplocale.c:53)
==7536==    by 0x4EA87D6: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA8BDA: std::locale::locale(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x40D68D: Relatorio::geraRelatorios() (Relatorio.cpp:23)
==7536==    by 0x402335: main (main.cpp:24)
==7536== 
==7536== 376 bytes in 1 blocks are still reachable in loss record 68 of 73
==7536==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7536==    by 0x5380664: duplocale (duplocale.c:53)
==7536==    by 0x4EB1E8D: std::__timepunct<wchar_t>::_M_initialize_timepunct(__locale_struct*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4ED6A27: std::__timepunct<wchar_t>::__timepunct(__locale_struct*, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA890C: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA8BDA: std::locale::locale(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x40D68D: Relatorio::geraRelatorios() (Relatorio.cpp:23)
==7536==    by 0x402335: main (main.cpp:24)
==7536== 
==7536== 376 bytes in 1 blocks are still reachable in loss record 69 of 73
==7536==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7536==    by 0x5380664: duplocale (duplocale.c:53)
==7536==    by 0x4ED71E0: std::messages<wchar_t>::messages(__locale_struct*, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA899F: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA8BDA: std::locale::locale(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x40D68D: Relatorio::geraRelatorios() (Relatorio.cpp:23)
==7536==    by 0x402335: main (main.cpp:24)
==7536== 
==7536== 400 bytes in 1 blocks are still reachable in loss record 70 of 73
==7536==    at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7536==    by 0x4EB1C29: std::__timepunct<char>::_M_initialize_timepunct(__locale_struct*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EBBC47: std::__timepunct<char>::__timepunct(__locale_struct*, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA85F2: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA8BDA: std::locale::locale(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x40D68D: Relatorio::geraRelatorios() (Relatorio.cpp:23)
==7536==    by 0x402335: main (main.cpp:24)
==7536== 
==7536== 400 bytes in 1 blocks are still reachable in loss record 71 of 73
==7536==    at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7536==    by 0x4EB25A9: std::__timepunct<wchar_t>::_M_initialize_timepunct(__locale_struct*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4ED6A27: std::__timepunct<wchar_t>::__timepunct(__locale_struct*, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA890C: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA8BDA: std::locale::locale(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x40D68D: Relatorio::geraRelatorios() (Relatorio.cpp:23)
==7536==    by 0x402335: main (main.cpp:24)
==7536== 
==7536== 576 bytes in 1 blocks are still reachable in loss record 72 of 73
==7536==    at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7536==    by 0x4EA8384: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA8BDA: std::locale::locale(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x40D68D: Relatorio::geraRelatorios() (Relatorio.cpp:23)
==7536==    by 0x402335: main (main.cpp:24)
==7536== 
==7536== 1,344 bytes in 1 blocks are still reachable in loss record 73 of 73
==7536==    at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7536==    by 0x4EA86A1: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x4EA8BDA: std::locale::locale(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==7536==    by 0x40D68D: Relatorio::geraRelatorios() (Relatorio.cpp:23)
==7536==    by 0x402335: main (main.cpp:24)

我只调用一次语言环境,它给了我一百次内存泄漏。

感谢。

2 个答案:

答案 0 :(得分:1)

在gcc(v5.3.0)的源代码中,构造函数locale::locale(在libstdc++-v3/src/c++98/localename.cc中)使用以下之一:

  • new _Impl (…):动态分配,可能是内存泄漏。
  • (_M_impl = _S_classic)->_M_add_reference();:静态引用,无内存泄漏。

析构函数locale::~locale(在libstdc++-v3/src/c++98/locale.cc中)调用_M_remove_reference(在libstdc++-v3/include/bits/locale_classes.h中)检查参考计数器并在必要时调用delete 。所以我不确切知道为什么会有内存泄漏。

在阅读locale::locale的构造函数后,我找到了一个技巧。离开您的申请后,请致电locale::global(locale("C"));。使用locale("C")不要在构造函数中使用new,而是使用_M_add_reference

因此,前一个区域设置(locale("pt_BR.UTF-8")将被销毁,并且不会通过分配创建新的区域设置。

答案 1 :(得分:1)

偶然发现了这个问题。

出于这个原因,我写了一个提供范围内语言环境的小帮手。对于使用区域设置的代码,如果使用valgrind测试代码,我会在from django.db.models import F Income.objects.filter(income_before_tax_lte = F('gross_profit')) 的开头设置它。在返回main时,语言环境将重置为main() - 至少在我的开发环境中。

"C"