Objekte einer Struktur richtig gelöscht?



  • Hallo 🙂

    Ich habe eine eigenene Objektstrukur erstellt. Wie viele Objekte dieser
    Struktur es gibt, verändert sich ständig und hängt davon ab wieviel 'Einheiten' im Speicher des Spiels existieren das ich auslese.

    Problem: Das Programm leaked. Debugger meldet Heap corrupted. Meine Vermutung ist das ich entweder:
    a) Die Objekte der Struktur falsch lösche. Ist "delete []Obj;" korrekt? Oder muss ich da mit for irgendwie durchloopen? *verwirrt* Beim debuggen wird mir jedenfalls der Fehler bei dem "delete []Obj" in der Fkt. ReadObjects() angezeigt
    b) Während das Spiel im Ladebildschirm die Zone/das Level wechelt verändert sich die Speicherstruktur. Mein Programm hört während dieser Zeit nicht auf damit den Speicher des Spiel auszulesen. Da das Auslesen auf einigen Pointern beruht die in dieser Zeit eventl. 0 sind könnte es zu einer Zugriffsverletzung kommen. Allerdingt müsste mir der debugger das dann anders anzeigen und ACCESS VIOLATION melden.

    // meine Struktur in der ich ausgelesene Objektdaten abspeichere
    struct SObj
    {
        int     type;
        __int64 guid;
        float   x;
        float   y;
        float   z;
        int     health;
        int     level;
        char    name[40];
    };
    
    // Cmem ist meine Klasse zum auslesen eines fremden prozesses
    class Cmem
    {
        private:
            // andere variablen hier - prozesshanle, wndhandle, pid, etc
        public:
            Cmem();
            ~Cmem();
            char        *ReadSTR(long addr);
            __int64     ReadINT64(long addr);
            long        ReadINT32(long addr);
            float       ReadFLOAT(long addr);
            double      ReadDOUBLE(long addr);
            SObj        *Obj;
            int         foundobjects;
            void        ReadObjects();
    };
    
    Cmem::Cmem()
    {
        foundobjects=0;
        Obj=0;
        // weitere variablen und pointer =0
    }
    
    Cmem::~Cmem()
    {
        delete []Obj;
        // handles schließen und andere Sachen löschen
    }
    
    // ReadObjects wird 20 mal pro Sekunde aufgerufen
    // Der ausgelesene Inhalt wird in einem OpenGL Fenster dargestellt
    void Cmem::ReadObjects()
    {
        delete []Obj;
        foundobjects=0;
        while ( ... )    // Pseudocode - Anzahl der Objekte ermitteln um dann x Objekte vom Typ SObj zu erstellen
        {
            // Hier wird geprüft ob ein weiteres Objekt im anderen Prozess zu finden ist
            // keins mehr da? -> break;
            foundobjects++;
        }
    
        // Speicher reservieren um alle Objekte auslesen zu können
        Obj = new SObj[foundobjects];
    
        int n=0;
        DWORD tmp;
        while ( ... )    // Pseudocode - Objekte auslesen und abspeichern
        {
            // Speicher eines anderen Prozess auslesen und Infos abspeichern
            Obj[n].type=3;
            Obj[n].x=2.0f;
            Obj[n].y=8.0f;
            Obj[n].z=1.0f;
            // Sind alle Objekte ausgelesen wird while verlassen
            n++;
        }
    }
    


  • sieht vom löschen und allokieren her ganz ok aus...

    also sollte kein speicherleck entstehen, jedenfalls nicht in dem code



  • Ok ich habe den Fehler gefunden.

    Dazu muss ich sagen das meine beiden While-Schleifen in der Read-Funktion durch eine Liste von Pointern im Speicher des Spiels springen. Der Fehler war: Ich ging davon aus das sich in der Zeit von Schleife 1 zu Schleife 2 der Speicher nicht verändert -> die zweite Schleife sollte so oft aufgerufen werden wie in 'foundobjects' gespeichert. Nun kommt es aber selten vor das in dieser sehr kurzen Zeit ein neues Objekt vom Spiel geladen wird. Das hat zur Folge das Schleife zwei einmal zu viel aufgerufen wird und versucht die Daten in die Bereicht volle 'Obj'-Struktor zu schreiben.

    Lösung? als erstes in die zweite while Schleife einbauen:

    if (n>=foundobjects)
    {
        break;
    }
    

    läuft hammergeil jetzt *wohoo* 👍
    Habe aber laaange gebraucht um das rauszufinden.


Anmelden zum Antworten