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

2

8

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.

Chyme answered 4/1, 2013 at 11:15 Comment(4)
Are you on a platform where Valgrind is an option?Chimerical
If you're working on linux, try to check your application with ValgrindCartoon
Have you defined copy constructor and assignment operator or explicitly disallowed copying of instances of the class that has member m_pVar?Sheathing
Just a note: it's perfectly safe to delete a nullptr. the check is unnecessaryMoreno
S
13

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.

Sidesaddle answered 4/1, 2013 at 11:22 Comment(1)
Thank you for the answer NPE! Sorry for a bit late reply, but I was still trying to find a problem according to hints you all gave me and I finally found it thanks to "Application Verifier" and "Debug Diagnostics Tool" programs. It appears that I've been using pointer to block of memory which was already freed.Chyme
C
3

Crash during malloc is a sure sign of memory corruption and it may or may not be due to double delete. Corruption happened in some different part of your code and unfortunately the effect ripples out in your failing code which is definitely innocent. If possible, try to port your application in a system where you can run valgrind

Classis answered 4/1, 2013 at 11:23 Comment(1)
Thank you Abhijit for the answer. The problem was using a pointer to block of memory which was already freed.Chyme

© 2022 - 2024 — McMap. All rights reserved.