5

In meiner Anwendung erhalte ich diese Fehlermeldung:Heap Korruption - "Free Heap Block 61af0f0 bei 61af194 geändert, nachdem er befreit wurde" C++

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

Hier ist ein Call-Stack:

[email protected]() Unknown 
    [email protected]@24() Unknown 
    [email protected]() Unknown 
    [email protected]() Unknown 
    [email protected]@24() Unknown 
    [email protected]() 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 
    [email protected]@12() Unknown 
    [email protected]() Unknown 
    [email protected]() Unknown 

Aus dem, was ich weiß, wird der Fehler, den ich erhalte, dadurch verursacht, dass ich den Speicherblock, der bereits freigegeben wurde, wieder aufrufen (löschen) kann. Es ist bereits ein dritter Tag, um herauszufinden, was genau mit meinem Code nicht stimmt. Während dieser Zeit habe ich einige kleine Speicherlecks gefunden, die ich bereits repariert habe, und jetzt sagt Visual Leak Detector, dass es kein Leck entdeckt.

Noch das Problem mit Heap Korruption bleibt.

An jeder Stelle meines Codes an einer Stelle, an der der Operator "delete" verwendet wird, überprüfe ich zuerst, ob ein Zeiger nicht nullptr ist. Wenn nicht, habe ich es zu nullptr:

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

So scheint es, als gäbe es kein Problem mit dem Frei gleichen Speicherblock mehr als einmal sein sollte.

Ich habe versucht, etwas aus diesem Call-Stack herauszufinden, aber das ist der Ort, an dem ich Sie um Hilfe bitten möchte. In einem Call-Stack scheint es, als wäre ein Problem mit string Allokation, aber was genau kann das bedeuten? Die letzte MY Funktion, die aufgerufen wird, ist string TUtil::intToString(int val) Line 43, so kann es einfacher sein, wenn ich Ihnen einen Körper dieser Funktion zeigen:

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

Manchmal rufen Stapel unterschiedlich ist, so string TUtil::intToString(int val) Funktion existiert nicht einmal darin, aber es hat IMMER etwas mit string s Zuweisungen zu tun.

Ich hoffe, es ist klar, was ich gerade gesagt habe. Wenn Sie mehr Informationen benötigen, bitte sagen Sie mir, und ich werde es in Bearbeitung für diese Frage bereitstellen.

+3

Sind Sie auf einer Plattform, wo Valgrind eine Option ist? –

+0

Wenn Sie unter Linux arbeiten, versuchen Sie, Ihre Anwendung mit Valgrind zu überprüfen. – Vargan

+2

Haben Sie den Kopierkonstruktor und den Zuweisungsoperator definiert oder das Kopieren von Instanzen der Klasse mit dem Member 'm_pVar' explizit verboten? – hmjd

Antwort

9

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

Es sei denn, etwas wissen Sie es und sagen uns nicht, kann der oben auch eine falsche Fährte sein. Der Fehler könnte auch bedeuten, dass Sie Speicher durch einen dangling Zeiger oder aufgrund eines Pufferüberlaufs ändern.

Wenn Sie jemals Kopien von Zeigern erstellen (entweder explizit oder indem Sie keine Kopierkonstruktoren/Zuweisungsoperatoren definieren), bietet die Einstellung m_pVar = nullptr beim Löschen keine Garantien für doppelte Löschungen, geschweige denn andere Arten von Speicherfehlern.

Wenn Sie das Problem nicht finden, indem Sie den Code untersuchen, ist Ihre beste Wette ein Tool wie Valgrind oder Purify.

+4

Danke für die Antwort NPE! Sorry für ein bisschen späte Antwort, aber ich habe immer noch versucht, ein Problem nach Hinweisen zu finden, die Sie mir gegeben haben und ich fand es schließlich dank "Application Verifier" und "Debug Diagnostics Tool" -Programmen. Es scheint, dass ich den Zeiger zum Speicherblock verwendet habe, der bereits freigegeben wurde. –

2

Absturz während malloc ist ein sicheres Zeichen für Speicherbeschädigung und es kann oder kann nicht wegen doppelter Löschung sein. Korruption ist in einem anderen Teil Ihres Codes aufgetreten und leider ist der Effekt in Ihrem fehlerhaften Code, der definitiv unschuldig ist, ausgebreitet. Wenn möglich, versuchen Sie, Ihre Anwendung in einem System zu portieren, in dem Sie Valgrind ausführen können

+0

Danke Abhijit für die Antwort. Das Problem bestand darin, einen Zeiger auf den Speicherblock zu verwenden, der bereits freigegeben wurde. –