【问题标题】:std::wstring_convert memory leakstd::wstring_convert 内存泄漏
【发布时间】:2016-08-23 01:42:09
【问题描述】:

我有一个真正的内存泄漏源于以下函数。

// Convert a UTF-8-encoded byte string to a wstring.
std::wstring Utf8ToWideString(const std::string& utf8str) {
  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> conv;
  return conv.from_bytes(utf8str);
}

我了解特定于语言环境的函数可能会为每个线程分配一次内存,并在线程的生命周期甚至整个进程中保留它(显然是happens here)。这不是我的情况;事实上,我在这个过程中有大约 2GB 的额外内存,并且这些明显泄漏的堆块中的大多数都是 2 种大小之一,并且包含(每个大小对应于每个大小)一个星期名称(...:Mon:Monday:Thu:...),还有一些时间格式。这些显然是每次通话都会泄露的。根据 WPA(一种工具跟踪分配,valgrind 在 Windows 领域的表亲),分配发生在对 CRT 函数 std::setlocale 的调用内部。此外,没有大的线程流失,如果不是所有的转换调用都来自同一个线程池,那么绝对大多数。

我的主要问题是:我是否正确使用了std::wstring_convert

第二个问题,如果我的代码中没有明显的错误或不常见的模式,这是一个已知问题吗?我的编译器是 MSVS 2015,更新 2 和更新 3 版本都会出现问题。

【问题讨论】:

    标签: c++11 memory-leaks visual-studio-2015


    【解决方案1】:

    根据http://en.cppreference.com/w/cpp/locale/wstring_convert 的说法,您对std::wstring_convert 的使用似乎没有任何问题。当然,这些设施应该适当地处理它们的内存,而不需要用户知道任何有关它的信息。

    这是否是 Visual Studio 标准库实现中的错误,我不知道。但是,我可以设想的一种可能情况是,它们将转换缓存为某种形式的优化。要查看是否是这种情况,您应该尝试重复转换相同的字符串,并查看是否只为第一次转换执行分配。

    最后一点,只要您没有耗尽内存或使用过多的内存,我就不会担心。虽然您可能想要进行“转换压力测试”,即执行多次分配,以查看内存使用量是否显着增加。

    【讨论】:

    • 感谢您确认我的代码 sn-p 的合理性。我一定会尝试提出最低限度的复制;目前,问题发生在使用来自多达 10 个不同工具集的库的大型服务器中。而且泄漏肯定太大而不能成为任何类型的缓存(我们谈论的是每天 GB 的 RAM处理)。
    猜你喜欢
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    相关资源
    最近更新 更多