c++memorymemory-leaksheap-corruptionvisual-leak-detector

Heap corruption - "Free Heap block 61af0f0 modified at 61af194 after it was freed" C++


In my application I'm getting this error:

HEAP[App.exe]: HEAP: Free Heap block 61af0f0 modified at 61af194 after it was freed

Here is a call stack:

    ntdll.dll!_RtlpBreakPointHeap@4()   Unknown
    ntdll.dll!@RtlpAllocateHeap@24()    Unknown
    ntdll.dll!_RtlAllocateHeap@12() Unknown
    ntdll.dll!_RtlDebugAllocateHeap@12()    Unknown
    ntdll.dll!@RtlpAllocateHeap@24()    Unknown
    ntdll.dll!_RtlAllocateHeap@12() Unknown
>   msvcr110d.dll!_heap_alloc_base(unsigned int size) Line 57   C
    msvcr110d.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 431 C++
    msvcr110d.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 239  C++
    msvcr110d.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine) Line 302    C++
    msvcr110d.dll!malloc(unsigned int nSize) Line 56    C++
    msvcr110d.dll!operator new(unsigned int size) Line 59   C++
    App.exe!std::_Allocate<char>(unsigned int _Count, char * __formal) Line 28  C++
    App.exe!std::allocator<char>::allocate(unsigned int _Count) Line 591    C++
    App.exe!std::basic_stringbuf<char,std::char_traits<char>,std::allocator<char> >::overflow(int _Meta) Line 152   C++
    msvcp110d.dll!std::basic_streambuf<char,std::char_traits<char> >::sputc(char _Ch) Line 196  C++
    msvcp110d.dll!std::ostreambuf_iterator<char,std::char_traits<char> >::operator=(char _Right) Line 634   C++
    msvcp110d.dll!std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::_Put(std::ostreambuf_iterator<char,std::char_traits<char> > _Dest, const char * _Ptr, unsigned int _Count) Line 1553  C++
    msvcp110d.dll!std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::_Iput(std::ostreambuf_iterator<char,std::char_traits<char> > _Dest, std::ios_base & _Iosbase, char _Fill, char * _Buf, unsigned int _Count) Line 1544 C++
    msvcp110d.dll!std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char,std::char_traits<char> > _Dest, std::ios_base & _Iosbase, char _Fill, long _Val) Line 1216   C++
    msvcp110d.dll!std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::put(std::ostreambuf_iterator<char,std::char_traits<char> > _Dest, std::ios_base & _Iosbase, char _Fill, long _Val) Line 1137  C++
    msvcp110d.dll!std::basic_ostream<char,std::char_traits<char> >::operator<<(int _Val) Line 311   C++
    App.exe!TUtil::intToString(int val) Line 43 C++
    App.exe!TFontManager::getFont(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & filename, int size) Line 15  C++
    App.exe!TButton::draw() Line 55 C++
    App.exe!TWindow::draw() Line 203    C++
    App.exe!TGUIManager::drawObjects() Line 49  C++
    App.exe!TGameAppLayer::gameCycle() Line 456 C++
    App.exe!TGameAppLayer::mainLoop() Line 520  C++
    App.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 36   C++
    App.exe!__tmainCRTStartup() Line 528    C
    App.exe!wWinMainCRTStartup() Line 377   C
    kernel32.dll!@BaseThreadInitThunk@12()  Unknown
    ntdll.dll!___RtlUserThreadStart@8() Unknown
    ntdll.dll!__RtlUserThreadStart@8()  Unknown

So from what I know, the error I'm getting is caused by accessing (deleting again) block of memory which was already freed. It's already a third day of trying finding out what exactly is wrong with my code. During this time, I found some small memory leaks which I already fixed, and now Visual Leak Detector tells me it doesn't detect any leak.

Yet the problem with heap corruption remains.

In each place of my code in a place where "delete" operator is being used, I check first if a pointer isn't nullptr. If not, I set it to nullptr:

if(m_pVar != nullptr)
{
    delete m_pVar;
    m_pVar = nullptr;
}

So it seems like there shouldn't be a problem with freeing same block of memory more than once.

I was trying to figure something out from this call stack, but that's place in which I'd like to ask you for a help. In a call stack it seems like a problem is with string allocation, but what exactly may this mean? The last MY function that is being called is string TUtil::intToString(int val) Line 43, so it may be easier if I show you a body of that function:

std::string TUtil::intToString(int val)
{
    std::ostringstream s;
    s << val;                 // Here's line 43
    return s.str();
}

Sometimes call stack is different, so string TUtil::intToString(int val) function doesn't even exist in it, but it ALWAYS has something to do with strings allocations.

I hope it's clear what I just said. If you need more information, please tell me and I'll provide it in edit to this question.


Solution

  • So from what I know, the error I'm getting is caused by accessing (deleting again) block of memory which was already freed.

    Unless there's something you know and are not telling us, the above can well be a red herring. The error could also mean that you're modifying memory through a dangling pointer, or due to a buffer overrun.

    If you ever make copies of pointers (either explicitly, or by failing to define copy constructors/assignment operators), setting m_pVar = nullptr upon deletion will provide no gurantees against double deletes, let alone other types of memory errors.

    If you can't find the problem by examining the code, your best bet might be a tool like Valgrind or Purify.