Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
ich arbeite ja zur Zeit an nem Spiel (i-wann werd ich es auch hier ankündigen). So neulich hab ich was geändert (wer hätte es gedacht) und seit dem bekomme ich beim Beenden folgende Fehlermeldung:
Natürlich hab ich schon debugt. Zuerst aber noch ein paar Infos: Ich hab mir eine kleine Memory-Leak-Detection geschrieben (also new + delete überladen), hier mal der Relevante Teil:
Die Funktion RemoveTrack entfernt einfach nur den Eintrag aus einer Liste. Wenn ich in Der Fehlermeldung auf "Wiederholen" klicke zeigt mir der Debugger die Zeile mit dem "free(p)" an. Wenn ich ein bisschen durch den Call-Stack gehe, um rauszufinden, welcher Speicher freigegeben werden sollte stelle ich fest, dass es Speicher von einer Klasse aufm Heap ist. Das ist logisch, denn an genau dieser Klasse habe ich änderungen vorgenommen. Ich weiß leider nicht mehr was ich alles geändert habe und ich kann es auch leider nicht mehr rückgängig machen (also letzte Revision vom svn herstellen), da ich schon viel zu viel geändert habe und das ein enormer Arbeitsverlust wäre.
Ein paar Fragen: Wie entsteht so ein Fehler? Braucht ihr eventuell noch ein bisschen mehr code? (Ich kann leider nicht viel rausgeben, da ich den Quellcode von diesem Spiel erstmal nicht freigeben werde). Braucht ihr noch Infos?
Alle Vorschläge sind willkommen, ich probier jetzt schon seit Tagen das Problem zu lösen.
Aber es ist fraglich, ob das alles hilfreich ist. Wenn du was an der Klasse verändert hast, liegt der Fehler vielleicht dort.
Musst du vielleicht etwas vererbungsspezifisches beachten?
ich vermute eher dass du 2mal den selben Bereich freigibst,
oder einen Bereich der garnicht reserviert wurde.
überpüfe das doch mal in der Liste beim entfernen des Eintrags,
wenn sich kein Eintrag in der Liste befindet hast du den Fehler.
Also der Pointer ist nicht 0 das sagt zumindest der Debugger. Die größe kann ich leider nicht prüfen, ich speicher sie zwar auch in meiner Liste nur ist die Frage, ob ich den delete Operator so überladen kann, dass er auch noch die größe übernimmt? Dass ich free benutze hat schon seinen Grund, denn ich benutze ja auch malloc um den Speicher zu reservieren und die Standard new + delete zu verwenden macht dann i-wie keinen Sinn mehr.
Ob ich vererbungsspezifische Dinge beachten muss? Eigentlich nicht, die Erzeugte Instanz ist von einer Interfaceklasse mit lauter pure-virtual Methoden abgeleitet. Diese wiederum ist von einer Reference counter Klasse abgeleitet, die nur die Methoden AddRef und Release implementiert (virtual) und halt den Ref. counter im protected Bereich.
Ich weiß leider nicht mehr was ich alles geändert habe und ich kann es auch leider nicht mehr rückgängig machen (also letzte Revision vom svn herstellen),
wozu gibt es diff? Vorallem kannst du über dein System doch feststellen, um was für ein Objekt es sich überhaupt handelt, welches den Fehler verursacht. Wahrscheinlich hast du einfach ein Objekt gelöscht, aber nicht alle Zeiger dabei erwischt (ggf. _ptr aus z.b. boost nutzen?).
Viele Corruption-Probleme entstehen in erster Linie einmal nicht dort, wo man es erwarten wuerde. Meist irgendwo ganz anderst...
Gruesse,
Mordrak, der sich an eine muehsam zu debuggende Heapcorruption erinnert, die immer erst ca. 5-10 Minuten spaeter und auch nur bei sehr speziellen Eingabedaten zu einem Absturz gefuehrt hat...
What's yellow and equivalent to the axiom of choice? The Lemmon of Zorn!
Wie dir die Fehlermeldung schon sagt, schreibt dein Programm über den auf dem Heap reservierten Speicherbereich hinaus.
Ein solcher Fehler wird zwar erst beim Aufruf von delete bzw. free bemerkt (da zu diesem Zeitpunkt bei einem Debug-Build die Heap-Datenstrukturen überprüft werden), der Fehler kann aber beliebig weit davor passiert sein.
Eine Möglichkeit ist, dass du einen bereits wieder freigegebenen Bereich weiterverwendest. Diesen Fall kann deine RemoveTrack() Funktion erkennen: wenn die aus der Liste zu löschende Adresse gar nicht in der Liste steht.
Eine andere Möglichkeit ist der Fall, dass du an irgend einer Stelle zu wenig Speicher reservierst. Der Klassiker wäre ein off-by-one Fehler bei der Nutzung eines Arrays (x Elemente reserviert und dann auf Index x zugreifen).
Aber auch wenn du für ein Objekt zu wenig Speicher reservierst, wird durch regulären Zugriff auf dessen Member über den reservierten Speicherbereich hinaus zugegriffen.
@Nox: Ja ich weiß ja welches Objekt gelöscht wird ich weiß welche Klasse es ist und dass es eigentlich nur eine Instanz davon gibt.
Ich beschreibe mal den groben Ablauf:
Mein Objektmanager hat einen Zeiger auf den ModManager (das ist die Klasse die Probleme macht). Er Ruft nun Release auf. Da Der Referenzzähler auf 1 steht löscht sich das Objekt selbst mit delete. Nun wird ja bekanntlich der Destruktor aufgerufen. Er löscht noch ein paar andere Objekte die Zeiger auf den ModManager haben. Dann kommt meine Memory-Leak-Detection zum Einsatz, denn der Speicher soll ja Freigegeben werden. Der Eintrag wird aus der Liste entfernt, dann kommt der Aufruf der free Funktion und dann kommt meine Meldung.
Ich probier grade mal, ob es eventuell Probleme mit boost gibt, das war nämlich eine der "größeren" Änderungen die ich gemacht habe, boost integriert (davor wurde es nicht benötigt).
Hey cool, Problem gelöst. Was genau ich gemacht habe was ich auch nicht, ich hab jedenfalls nachdem ich Boost wieder rausgenommen hab und das auch nicht geholfen hab ich es wieder eingebaut. Dann hab ich noch 2 unordentliche c'tors (Vom Objektmanager und vom Modmanager) neu geschrieben und eine Lade-Methode. Jetzt geht es wieder und ich kann endlich weiter Programmieren (ich hab über ne Woche an dem Fehler gesucht).