heap probleme mit std::vector
-
Hi, ich habe folgendes Problem:
Beim debuggen meines Programmes bekomme ich Fehlermeldungen, dass eine unbehandelte Ausnahme aufgetreten ist. Die Fehlerausgabe verweist bei diesem Fehler immer auf eine heap corruption. Wenn ich das Programm debugge tritt der Fehler recht zufällig auf (nicht reproduzierbar).
Ich arbeite in meinem Programm unter anderem mit einem Nebenthread. Nebenthread und Hauptthread greifen dabei auf einen container (std:vector) zu. Auffällig ist, dass die zuletzt vor dem Fehler aufgerufenen Funtionen sich in der Regel auf Operationen mit dem Vector beziehen (z.B. push_back). Die Zugriffe auf den Vector habe ich mit kritischen Abschnitten synchronisiert.
Was ebenfalls auffällig ist, ist dass das Programm unter Visual Studio .net 2005 einwandfrei läuft (habe es auch hier getestet), jedoch unter Visual Studio .net 2003 der Fehler auftritt.
Hat Irgendeiner eine Ahnung woran das liegen könnte?
-
Wenn Du aus mehr als einem Thread auf gemeinsame Daten zugreifst, dann *musst* Du die Zugriffe synchronisieren!
Das einfachste ist eine Critical-Section (CS) dazu zu verwenden.Also immer, wenn Du auf den std::vector zugreifen willst, musst Du die Aufrufe in eine CS einklammern:
EnterCriticalSection(&cs); vect.push_back(val); LeaveCriticalSection(&cs);Du musst natürlich aufpassen, dass keine Exception geworfen wird, sonst wird diese CS nie wieder freigegeben...
-
Das ist gerade mein Problem - genau so habe ich auch die kritischen Abschnitte implementiert, aber trozdem treten die Fehler auf.
-
Benutzen auch beide Threads dieselbe Critical Section?
Fall ja, dann schreibst du vermutlich irgendwo über die Grenzen des vectors hinweg. Ersetz mal alle Aufrufe von operator[] durch at().
-
So, habe jetzt alle Elementzugriffe von [] auf at() umgeschrieben.
Die Fehler treten immer noch auf. Die beim Debuggen ausgegebenen Meldungen im Mitteilungsfenster lauten etwa folgendermaßen (kamen vorher allerdings auch schon):Unbehandelte Ausnahme bei 0x7c812a5b in Test_program.exe: Microsoft C++ exception: std::bad_alloc @ 0x0057f748.
Beide Threads benutzen dieselbe critical section.
-
Die Ausgabe des Debuggers ab Auftreten des Fehlers sah in diesem Falle folgendermaßen aus:
Heap corruption detected at 00580A28
Eine Ausnahme (erste Chance) bei 0x7c936a36 in Test_program.exe: 0xC0000005: Zugriffsverletzung-Schreibposition 0xdddddddd.
Eine Ausnahme (erste Chance) bei 0x7c921e58 in Test_program.exe: 0xC0000005: Zugriffsverletzung-Leseposition 0xdddddddd.
Heap corruption detected at 00320CF8
Eine Ausnahme (erste Chance) bei 0x7c92b56d in Test_program.exe: 0xC0000005: Zugriffsverletzung-Schreibposition 0xdddddddd.
Eine Ausnahme (erste Chance) bei 0x7c812a5b in Test_program.exe: Microsoft C++ exception: std::bad_alloc @ 0x0057f748.
Unbehandelte Ausnahme bei 0x7c812a5b in Test_program.exe: Microsoft C++ exception: std::bad_alloc @ 0x0057f748.
Der Thread 'Win32 Thread' (0x528) hat mit Code 0 (0x0) geendet.
Das Programm "[308] Test_program.exe: Systemeigen" wurde mit Code 0 (0x0) beendet.
-
Dann kracht es offensichtlich wenn der vector wächst. Ist jeder Bereich bei dem auf den Vector zugegriffen wird entsprechend abgesichert.
Edit:
Ich würde sagen, dass hier sagen dass Du auf Speicher zugreifst, der schon wieder freigegeben ist. Das zeigt schon die Adresse 0xdddddddd an!
Ich vermute, Du hast einen Zeiger in den Vector gespichert und wenn dieser wächst wird dieser natürlich ungültig.
-
Ja, jeder - hab ich schon mehrfach überprüft.
-
XPins schrieb:
Ja, jeder - hab ich schon mehrfach überprüft.
Was genau hast du jetzt überprüft?
Speicherst du irgendwo einen Zeiger oder eine Referenz auf ein Element des Vectors, das durch eine zwischenzeitliche Größenänderung ungültig werden könnte?
Ist dir klar, dass du, wenn du z.B. über den Vector iterierst, die gesamte Schleife in die Critical Section stecken muss, und nicht nur die Elementzugriffe?
-
Du könntest die "Debugging Tools for Windows" installieren und dann mit "gflags.exe" Dein prozess markieren ("Image file"-Tab), dass er alle möglichen Heap-Checks machen soll. Dann findet er i.d.R. den Fehler schon da, wo er auftritt... und natürlich den "Page heap" aktivieren...
-
Beide Threads benutzen dieselbe critical section und jeder Programmabschnitt mit Zugriff auf den Vektor ist entsprechend abgesichert (Schleifen mit elementweisen Zugriffen auf den Vektor befinden sich ebenfalls komplett in critical sections.)
Zeiger/Referenzen, die gezielt auf Vektorelemente zugreifen gibt es bei mir keine (zumindest keine außerhalb einer critical section).
@ Jochen Kalmbach: Ich habe mir mittlerweile ein Debugging Tool von IBM runtergeladen und werde mich mal damit auseinandersetzen.
Vielen Dank schonmal für die Hinweise bis jetzt
-
Ähh.... wenn Du ein MS-OS hast, würde ich eher die von MS nehmen....
http://www.microsoft.com/whdc/devtools/debugging/default.mspx