Zum Inhalt springen

merkwürdiges Problem


Sloenig

Empfohlene Beiträge

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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".
Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

@ 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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 :rolleyes: . (/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...)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...