2017-02-09 6 views
-1

У меня есть консольное приложение Win32. Когда я запускаю этот код, это исключение составляет почти 60% времени.Сбой при освобождении кучи

Необработанное исключение в 0x777BC799 (ntdll.dll) в x.exe: 0xC0000374: куча повреждена (параметры: 0x777E8890).

void function(CString &outputStr, const char* name, DWORD64 value){ 
    outputStr = _T(""); 
    CString csName(name); 
    outputStr.Format(_T("<name=\"%s\" value=\"0x%08x\"/>\n"), csName, value); 
} 

Это одна из функций, где авария происходит (в последней строке). Когда я вижу StackTrace это примерно так:

[email protected]() 
[email protected]() 
[email protected]@12() 
[email protected]() Unknown 
abc.exe!ATL::CWin32Heap::Free(void * p) Line 153 C++ 
abc.exe!ATL::CAtlStringMgr::Free(ATL::CStringData * pData) Line 107 C++ 
abc.exe!ATL::CStringData::Release() Line 92 C++ 
abc.exe!ATL::CSimpleStringT<char,0>::~CSimpleStringT<char,0>() Line 263 C++ 
abc.exe!ATL::CStringT<char,ATL::StrTraitATL<char,ATL::ChTraitsCRT<char> >  ::~CStringT<char,ATL::StrTraitATL<char,ATL::ChTraitsCRT<char> > >() Line 1295C++ 

Другой блок кода, где авария случиться

std::string dir = ""; 
dir = dir + "\\" + "abc"; 

с аналогичной трассировки стека. Раньше путем отладки я видел шаблон, в котором произошел сбой только там, где происходит манипуляция строками (CString или std :: string). Как показано в стеке, авария происходит, когда функция Free вызывается внутренне при возврате из функционального блока. Теперь я не знаю, почему это происходит.

+0

Вопросы, требующие помощи по отладке («** почему этот код не работает? **)) должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для его воспроизведения ** в самом вопросе ** , Вопросы без ** ясного заявления о проблеме ** не полезны для других читателей. См. [Как создать минимальный, завершенный и проверяемый пример] (http://stackoverflow.com/help/mcve). – Biffen

+0

, не зная о Windows, однако, пожалуйста, убедитесь, что использование '_T' правильное. Я считаю, вам нужна поддержка Unicode в компиляторе: [см. Здесь] (http://stackoverflow.com/a/15498147/5112564) , Возможно, ваша строка предназначена для символов 'char', когда вы хотите дать ей символы' wchar_t' - в результате вы получаете повреждение кучи, потому что больше памяти было выделено, чем система знает. Это может быть результат '.Format (** _ T ** ...)' - 'csName' (а также' outputStr'?) Построен из 'char', а вместо этого вы предоставляете' unicode' – andrgolubev

+1

Это очень вероятно, что куча повреждена в другом месте и просто отображается для несвязанного кода, также используя кучу. Мы можем быть уверены, что 'CString' и' std :: string' не развращают кучу. –

ответ

0

Проблема исправлена. Вообще-то я найти папку Programdata с помощью

wchar_t *additionalPath = L"\\SomePath\\SomeMorePath"; 
wchar_t *appDataPath; 
SHGetKnownFolderPath(FOLDERID_ProgramData, 
    KF_FLAG_CREATE, 
    NULL, 
    &appDataPath) == S_OK) 

PathAppend(appDataPath, additionalPath); 

Теперь эта функция выделяет достаточно памяти для appDataPath и записывает значение в нем. Функция PathAppend внутренне добавляет addPath к appDataPath. Поскольку память, которая была назначена appDataPath, была ограничена, существует вероятность того, что эта функция добавит дополнительную строку и расширит значение за пределами выделенной памяти. Это приводит к повреждению кучи, когда к этой памяти обращается любая другая часть кода.

Смежные вопросы