Visual C++ 2013 Memory Leak Wostringstream, Imbue & locale facets
visual c++ 2013 memory leak wostringstream, imbue & locale facets
与我之前的问题有关,我假设内存泄漏发生在std::string中,但深入研究后,我得到了一些奇怪的结果。让我们开始:
考虑我们有一个全球
static volatile std::wostringstream *Log = nullptr;
在WriteToLog()函数中,我们有以下代码:
std::wostringstream* new_log = new std::wostringstream(std::ios::in | std::ios::out);
new_log->imbue(CConsumer::GetUtf8Locale());
std::wostringstream* old_log = (std::wostringstream*)Log;
while((std::wostringstream *)::InterlockedCompareExchangePointer((PVOID volatile *)&Log, new_log, (PVOID)old_log) != new_log)
{
::SleepEx(10, FALSE);
}
std::string logtext(Hooker::Utf16ToUtf8(old_log->str()));
使用专有技术:
static std::locale FORCEINLINE GetUtf8Locale()
{
static std::unique_ptr<std::codecvt_utf8_utf16<wchar_t>> code_cvt(new std::codecvt_utf8_utf16<wchar_t>(std::codecvt_mode::generate_header | std::codecvt_mode::little_endian));
return std::locale(std::locale(), code_cvt.get());
}
由于日志事件偶尔发生,它会产生巨大的内存泄漏(从最初的5MB/500句柄,几分钟内就会跳到200MB/300000句柄)。
以前,我认为这是一个与std::string有关的泄漏,但使用Visual Studio Profiler,它显示所有泄漏都是由GetUtf8Locale()引起的。
有人能帮我解决这个问题吗?
这个答案是错误的,我忽略了"比较";InterlockedCompareExchangePointer的一部分。然而,我认为这是朝着正确的方向迈出的一步
因此,我们从一个Log
成员指向0x87654321
的对象开始。然后两个线程调用WriteToLog
Thread1 Thread2
...new_log=new ...
(now new_log=0x15331564)
...new_log=new ...
(now new_log=0x25874963)
...old_log=Log;
(now old_log=0x87654321)
...old_log=Log;
(now old_log=0x87654321)
InterlockedCompareExchangePointer
(now new_log=0x87654321)
(now Log=0x15331564)
InterlockedCompareExchangePointer
(now new_log=0x15331564)
(now Log=0x25874963)
...stuff... ...stuff...
delete old_log
(now 0x87654321 is deleted)
delete old_log
(now 0x87654321 is deleted TWICE!)
并且Log
成员指向0x25874963
,所以…日志0x15331564
泄露!
您对InterlockedCompareExchangePointer
的使用不正确。我认为这是正确的,这取决于您尚未显示的代码。
std::wostringstream* new_log = new std::wostringstream(std::ios::in | std::ios::out);
new_log->imbue(CConsumer::GetUtf8Locale());
std::wostringstream* old_log = ::InterlockedExchangePointer((PVOID volatile *)&Log.get(), new_log);
std::string logtext(Hooker::Utf16ToUtf8(old_log->str()));
delete old_log;
相关文章:
- std::cout.imbue()多重调用
- 与 boost::locale 关于"ß"大写的例外行为混淆
- 使用 std::locale 格式化法语数字时无效的 UTF-8 数据
- C++ std::locale( "en" ) 在 iOS 上引发异常
- 为什么 boost::locale::to_title 不返回预期的输出?
- sf::Windows上的音乐:api-ms-win-crt-locale-l1-1-0.dll:无法打开共享对象文件
- 为什么 std::locale( " " ).name() 在 clang 和 gcc 上给出不同的结果?
- std::locale 向"en_US.UTF-8"区域设置抛出runtime_error异常
- 为什么当我将 std::locale 设置为 "zh_CN.UTF-8" 时 std::istringstream 失败?
- Unicode 字符分类与 boost::locale
- 更改狭窄的字符串编码或丢失std :: filesystem :: path :: imbue
- C++11:std::locale::empty() 甚至是一个东西
- 如何为android构建boost::locale
- std::locale 导致 Helgrind 出错
- STD :: LOCALE与LCONV :: P_CS_PRECEDES没有等效
- 对 boost::locale:conv::between 的未定义引用
- std::locale/std::facet关键部分
- Visual C++ 2013 Memory Leak Wostringstream, Imbue & locale facets
- 为什么cout.imbue(locale( " " ))会导致内存泄漏?
- Boost::filesystem::path::imbue失败,默认的std::locale()