Sloenig Geschrieben 9. August 2007 Geschrieben 9. August 2007 Hallo, wie der Titel des Themas schon sagt hab ich in meinem Programm einen sehr komischen Fehler. Und zwar meldet der mir bei der Ausführung nach einer gewissen Zeit eine nicht abgefangene Ausnahme vom Typ Access Violation. Soweit nicht weiter verwunderlich. Das merkwürdige dabei ist aber, dass das Programm im Debug Modus an einer Stelle diesen Fehler meldet, an welcher dieser sehr unlogisch ist. Im Debugmodus habe ich dann gesehen, dass der Fehler daran liegt, dass ein Pointer auf eine Struktur mit dem Operator new keinen Speicherplatz zugewiesen bekommt, also auf NULL zeigt. Allerdings weise ich dem betroffenen Pointer eine Zeile vorher mit dem new Operator einen Speicherbereich zu. Und das allerkomischste ist, dass es nicht immer passiert. Diese Methode wird mehrere Male vorher schon durchlaufen ohne diesen Fehler zu melden. Erst nach einer gewissen Zeit wird das Programm mit entsprechendem Fehler beendet. Falls dies von wichtigkeit ist: IDE ist MSVC++ und OS WinXP SP2 Hat jemand von euch vielleicht eine Ahnung woran das liegen kann? Hoffe ich habe mich verständlich ausgedrückt. Vielen Dank schonmal im voraus für eure Antworten. Sloenig Zitieren
Guybrush Threepwood Geschrieben 9. August 2007 Geschrieben 9. August 2007 Sehr wahrscheinlich schreibst du irgendwo über Feldgrenzen hinaus, also mehr in einen Speicherbereich als hineinpasst, so dass später beim Zugriff auf den überschriebenen Speicher Fehler auftreten. Zitieren
Sloenig Geschrieben 9. August 2007 Autor Geschrieben 9. August 2007 wäre eine möglichkeit, aber warum weist der bei folgendem Befehl dem Pointer den Speicherbereich NULL zu? SSharedMem* ptrInsertThreshold = new SSharedMem; Zitieren
Klotzkopp Geschrieben 9. August 2007 Geschrieben 9. August 2007 Ich sehe das ähnlich wie Guybrush Threepwood. wäre eine möglichkeit, aber warum weist der bei folgendem Befehl dem Pointer den Speicherbereich NULL zu?Sobald du durch Zugriffe über Speicherbereichsgrenzen hinweg undefiniertes Verhalten auslöst, kann alles passieren. Da erübrigen sich Fragen nach dem "warum". Zitieren
Mephisto81 Geschrieben 9. August 2007 Geschrieben 9. August 2007 hallo, wäre eine möglichkeit, aber warum weist der bei folgendem Befehl dem Pointer den Speicherbereich NULL zu? SSharedMem* ptrInsertThreshold = new SSharedMem; soweit ich weiß gibt ein "new"-Aufruf NULL zurück, wenn kein Speicher mehr allokiert werden konnte (aus welchen Gründen auch immer) - kann aber compilerabhängig sein. Hast du mal probiert dein Programm mit Exception-Unterstützung zu kompilieren und dann den entsprechenden Teil in einen try...catch-Block zu setzen, in dem du die Exceptions "std::bad_alloc" oder "std::exception" fängst? greetz mep /Edit: Habe gerade interessehalber nochmal nachgelesen: Die Exception-Geschichte funktioniert bei den Microsoft Compilern leider nicht bei jeder Version - nachzulesen unter: Operator new does not throw a bad_alloc exception on failure in Visual C++, deswegen wäre es auch noch interessant welche Version von MSVC++ du verwendest. Zitieren
Sloenig Geschrieben 9. August 2007 Autor Geschrieben 9. August 2007 benutze 6.0 Enterprise Edition hab grade mal in der msdn nachgelesen für den Operator new. Und der gibt NULL zurück wenn nicht genügend Speicher für die allokierung vorhanden ist. Also wäre es möglich, dass ich in meinem Programm nen übelstes Memory-Leak hab, oder bin ich da jetzt komplett verkehrt? Zitieren
Mephisto81 Geschrieben 9. August 2007 Geschrieben 9. August 2007 hallo, benutze 6.0 Enterprise Edition hab grade mal in der msdn nachgelesen für den Operator new. Und der gibt NULL zurück wenn nicht genügend Speicher für die allokierung vorhanden ist. Also wäre es möglich, dass ich in meinem Programm nen übelstes Memory-Leak hab, oder bin ich da jetzt komplett verkehrt? ja, wäre (nach den hier gegebenen Informationen) meines Erachtens nach die naheliegendste Ursache. Schade das Version 6.0 zu den Versionen gehört die diese Exception nicht werfen, sonst hätte man nähere Informationen durch Aufruf der Funktion std::bad_alloc::what() bekommen können. Die Suche nach Memory-Leaks klingt für mich am erfolgversprechendsten. Viel Erfolg dabei. greetz mep Zitieren
Klotzkopp Geschrieben 9. August 2007 Geschrieben 9. August 2007 Wieviel Speicher allokiert denn so ein SSharedMem-Objekt? Zitieren
Mephisto81 Geschrieben 11. August 2007 Geschrieben 11. August 2007 hallo, @Sloenig: falls du das Problem mittlerweile gelöst hast, wäre es interessant zu wissen, woran es dann am Ende lag greetz mep Zitieren
Sloenig Geschrieben 14. August 2007 Autor Geschrieben 14. August 2007 Bisher ist das Problem leider noch nicht gelöst. Suche gerade nach memory leaks, da ich Freitag und gestern Schule hatte. @ Klotzkopp: so ein SSharedMem Objekt allokiert ca. 2kB Zitieren
Klotzkopp Geschrieben 14. August 2007 Geschrieben 14. August 2007 @ Klotzkopp: so ein SSharedMem Objekt allokiert ca. 2kB Steigt denn der Speicherverbrauch deines Programms stetig an? Das kannst du z.B. mit dem Taskmanager kontrollieren. Wenn Windows der physische Speicher ausgeht, dann wird die Auslagerungsdatei benutzt. Wenn die auch voll ist, wird sie normalerweise automatisch vergrößert. Das sollte sich durch eine extreme Verlangsamung des Computers und andauernde Festplattenaktivität bemerkbar machen. Ist das bei dir der Fall? Wenn nicht, hast du vermutlich kein Memory Leak, sondern einen kaputten Heap. Zitieren
Sloenig Geschrieben 14. August 2007 Autor Geschrieben 14. August 2007 also es wird schon stetig größer aber nicht so groß das der physische Speicher voll ist und schon gar nicht, dass die Auslagerungsdatei vergrößert wird. Zitieren
Klotzkopp Geschrieben 14. August 2007 Geschrieben 14. August 2007 Dann würde ich nicht weiter nach einem Leck suchen, sondern nach einer Stelle, wo du auf Speicher zugreifst, der dir nicht gehört. Typische Kandidaten sind hier Bereichsüberschreitungen bei Arrays. Zitieren
Mephisto81 Geschrieben 14. August 2007 Geschrieben 14. August 2007 hallo, Und das allerkomischste ist, dass es nicht immer passiert. Diese Methode wird mehrere Male vorher schon durchlaufen ohne diesen Fehler zu melden. Erst nach einer gewissen Zeit wird das Programm mit entsprechendem Fehler beendet. also es wird schon stetig größer ... hört die Kurve denn irgendwann auf zu steigen? Hast du das Programm mal längere Zeit mit dem Speicher-Monitor (damit meine ich das Programm unter Systemsteuerung > Verwaltung > Leistung) laufen lassen und die Kurve beobachtet? Du als Programmierer weißt ja wo wie und wann du Speicher per new anforderst und wann du ihn wieder freigibst - ist für dich der Verlauf der Kurve erklärbar? Für mich ist und bleibt es aufgrund der Aussagen von oben ein Speicherproblem (just my two cents ). greetz mep Zitieren
Guybrush Threepwood Geschrieben 14. August 2007 Geschrieben 14. August 2007 Das lässt nicht unbedingt auf ein Memory Leak schließen, sondern sagt lediglich das entweder der Speicher erst zu einer späteren Zeit zwischen den einzelnen durchläufen zerstört wird oder das erst dann auf die zerstörte Stelle zugegriffen wird. Wenn man es mit einem Programm schaffen würde denn kompletten virtuellen Speicher mit 2KB Blöcken zu verbrauchen würden sich noch ein paar andere Dinge bemerkbar machen als das nur das Programm eine Exception schmeißt. Zitieren
Mephisto81 Geschrieben 14. August 2007 Geschrieben 14. August 2007 hallo, Und zwar meldet der mir bei der Ausführung nach einer gewissen Zeit eine nicht abgefangene Ausnahme vom Typ Access Violation. Soweit nicht weiter verwunderlich. [...] Im Debugmodus habe ich dann gesehen, dass der Fehler daran liegt, dass ein Pointer auf eine Struktur mit dem Operator new keinen Speicherplatz zugewiesen bekommt, also auf NULL zeigt. Allerdings weise ich dem betroffenen Pointer eine Zeile vorher mit dem new Operator einen Speicherbereich zu. die Access-Violation (so habe ich den Threadersteller verstanden) kommt dadurch zustande, dass der Speicherbereich einer Struktur NULL ist nachdem er versucht mit "new" neuen Speicher zu allokieren was aber laut seiner Aussage fehlgeschlagen ist: wäre eine möglichkeit, aber warum weist der bei folgendem Befehl dem Pointer den Speicherbereich NULL zu? SSharedMem* ptrInsertThreshold = new SSharedMem; Somit ist die Access-Violation schon absolut geklärt, vorausgesetzt der Threadersteller lügt uns nicht an, was ich dann auch gleich mal bezweifeln möchte . (/Edit: Beim Zugriff auf Nullpointer sind Access-Violations für mich ziemlich erklärbar. ) Ausserdem: also es wird schon stetig größer Das lässt nicht unbedingt auf ein Memory Leak schließen Wenn nicht das, was denn dann? Bevor uns der Threadersteller nicht gesagt hat, wie lange das Programm braucht bis es abstürzt bzw ob der Speicher irgendwann (erklärbar) aufhört anzusteigen, kann man die Möglichkeit eines mem leaks nicht ausschließen. greetz mep (der sich gerne vom Gegenteil seiner Meinung überzeugen lässt, bisher aber noch weit davon entfernt ist...) Zitieren
Klotzkopp Geschrieben 14. August 2007 Geschrieben 14. August 2007 Somit ist die Access-Violation schon absolut geklärt,Ja, da sind wir derselben Meinung. Die Frage ist, warum new 0 zurückgegeben hat. Eine Möglichkeit ist, dass der Speicher wirklich voll ist. Eine andere ist, dass Sloenig sich den Heap zerlegt hat. Ich zweifle nicht daran, dass da auch ein Speicherleck drin sein kann. Ich glaube nur nicht, dass es die Ursache des Absturzes ist. Wenn man Speicher in 2K-Blöcken anfragt, ohne sie wieder freizugeben, dann wirkt sich das nach meinen Erfahrungen eher so aus, dass Windows immer langsamer wird und schließlich nur noch mit Auslagern beschäftigt ist und damit praktisch stehenbleibt. Das ist aber anscheinend nicht der Fall. Um wirklich eine Out-of-memory-Situtation zu provozieren, muss man IMHO einen so großen Block anfordern, dass Windows vor der Allokation noch funktionsfähig war. 2 KByte-Häppchen reichen da nicht. Darum tippe ich auf den kaputten Heap. Zitieren
Sloenig Geschrieben 14. August 2007 Autor Geschrieben 14. August 2007 also ein memory leak ist definitiv drin, da es zwar nachvollziehbar ist, dass der Speicher allokiert wird, aber leider nicht, dass der Speicher nicht wieder freigegeben wird. Selbst wenn er nach starten des Programms noch eine gewisse Zeit Speicher allokiert sollte das nach einiger Zeit aufhören. Die Zeit bis das Programm abstürzt lässt sich leider nicht genau sagen. Ist immer unterschiedlich. Manchmal nach einigen Sekunden aber es kann auch sein, dass das Programm mehrere Minuten läuft. Und das ist auch direkt nach einem Neustart des Rechners so. Meine erste Vermutung war, dass ich den Speicher so vollgemacht habe, indem ich das Programm sehr oft geöffnet und laufen lassen habe und anschließend wieder geschlossen habe um einen Fehler zu beheben oder Features hinzuzufügen. Zitieren
Klotzkopp Geschrieben 14. August 2007 Geschrieben 14. August 2007 Meine erste Vermutung war, dass ich den Speicher so vollgemacht habe, indem ich das Programm sehr oft geöffnet und laufen lassen habe und anschließend wieder geschlossen habe um einen Fehler zu beheben oder Features hinzuzufügen.Dadurch kann der Speicher nicht vollaufen. Wenn dein Programm abstürzt oder du es schließt oder abschießt, gibt Windows den gesamten angeforderten Speicher wieder frei. Wenn die geschilderten Symbole - Windows wird langsam und die Festplatte arbeitet durchgehend - bei dir nicht auftreten (es wäre übrigens nett, wenn du das mal klarstellen würdest), dann ist das Speicherleck nicht dein primäres Problem. Zitieren
Sloenig Geschrieben 14. August 2007 Autor Geschrieben 14. August 2007 Wenn die geschilderten Symbole - Windows wird langsam und die Festplatte arbeitet durchgehend - bei dir nicht auftreten (es wäre übrigens nett, wenn du das mal klarstellen würdest), dann ist das Speicherleck nicht dein primäres Problem. tritt nicht auf Zitieren
maddin Geschrieben 14. August 2007 Geschrieben 14. August 2007 Ich habe das aber richtig verstanden, die Access Violation tritt nach der Zeile mit dem new auf und nicht in dieser Zeile. Sonst würde ich den Konstruktor noch einmal genauer unter die Lupe nehmen. Ansonsten tippe ich einfach einmal, dass du dich irgendwo in deinem Code mit einen Zeiger verschossen hast, oder Feldgrenzen überschreitest. Allgemein: Überprüfen, Überprüfen, Überprüfen !!! Die zweile nach dem new muss auf jeden Fall lauten: if (ptrInsertThreshold == 0) // Fehlerbehandlung. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.