Frage zu TComponentList und CodeGuard



  • Hallo.

    Ich habe im Header

    private:
    TComponentList *liste;
    

    und in der Unit

    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
        liste = new TComponentList;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
        delete liste;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        liste->Add(Memo1);
    }
    

    Klappt auch "scheinbar" aber wenn ich CodeGuard aktiviere und damit compiliere und das Programm beenden ist alles OK. Drücke ich jedoch vor dem Beenden den Button1 und möchte anschliessend beenden kommt:

    Im Project1.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung: 'Zugriffsverletzung bei Adresse 40025C9A in Modul 'VCL50.BPL'. Lesen von Adresse 8894889C'.

    Warum? Mach ich etwas falsch?

    Das selbe passiert auch wenn ich zweiten Button mit diesem Code einfüge

    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
        TMemo *Memo = new TMemo(this);
        Memo->Visible = true;
        Memo->Parent = Form1;
        Memo->Left = 100;
        Memo->Top = 100;
        //delete Memo;
        liste->Add(Memo);
    }
    

    Ist das lediglich ein Bug im CodeGuard?

    CodeGuard sagt in CGL Datei

    Fehler 00001. 0x100430 (Thread 0x070C):
    Zugriff in freigegebenem Speicher: Es wurde versucht, auf 4 Byte(s) bei
    0x011B7490 zuzugreifen.
    Aufrufhierarchie:
    0x004021EA(=Project1.exe:0x01:0011EA) C:\Programme\Borland\CBuilder5\Projects\TComponentList\Unit1.cpp#24
    0x400539C5(=VCL50.BPL:0x01:0529C5)
    0x40054117(=VCL50.BPL:0x01:053117)
    0x4006DF7B(=VCL50.BPL:0x01:06CF7B)
    0x400511D6(=VCL50.BPL:0x01:0501D6)
    0x7E368734(=user32.dll:0x01:007734)

    Speicherblock (0x011B7490) [Größe: 24 Byte] war zugewiesen mit SysGetMem
    Aufrufhierarchie:
    0x40002C3A(=VCL50.BPL:0x01:001C3A)
    0x00402099(=Project1.exe:0x01:001099) C:\Programme\Borland\CBuilder5\Projects\TComponentList\Unit1.cpp#19
    0x40053323(=VCL50.BPL:0x01:052323)
    0x4005301F(=VCL50.BPL:0x01:05201F)
    0x4005ABFC(=VCL50.BPL:0x01:059BFC)
    0x00401C21(=Project1.exe:0x01:000C21) C:\Programme\Borland\CBuilder5\Projects\TComponentList\Project1.cpp#13

    Speicherblock (0x011B7490) war freigegeben mit delete
    Aufrufhierarchie:
    0x32553990(=CC3250MT.DLL:0x01:052990)
    0x3255289A(=CC3250MT.DLL:0x01:05189A)
    0x32552ABA(=CC3250MT.DLL:0x01:051ABA)
    0x00403521(=Project1.exe:0x01:002521)
    0x7C91378B(=ntdll.dll:0x01:00278B)
    0x4000407B(=VCL50.BPL:0x01:00307B)

    C:\Programme\Borland\CBuilder5\Projects\TComponentList\Unit1.cpp#24
    ist: delete liste;

    C:\Programme\Borland\CBuilder5\Projects\TComponentList\Unit1.cpp#19
    ist: liste = new TComponentList;

    C:\Programme\Borland\CBuilder5\Projects\TComponentList\Project1.cpp#13
    ist: Application->CreateForm(__classid(TForm1), &Form1);

    Wäre super wenn das wer erklären könnte 🙂



  • Hallo

    Der Fehler im ersten Quellcode ist klar : Memo1 ist sicher eine IDE-verwaltete Komponenten. Damit ist auf jedenfall TForm1 für das Löschen dieser Komponente zuständig. Du setzt aber zusätzlich noch die TComponentList ein, das nun ebenfalls die Komponente löscht. Hier sollte als einfachste Lösung die Eigenschaft TComponentList::OwnsObjects helfen.

    Im zweiten Fall kann ich jetzt nicht 100% einen Fehler nachvollziehen, dürfte aber den selben Grund haben.

    ozu brauchst du überhaupt die TComponentList? Wenn du wirklich eine Untergruppe von Komponenten brauchst nimm lieber std::vector<TComponent*>, das kann nämlich direkt von TForm verwended werden und erfordert für sich selber keine dynamische Erstellung wie TC..L. Und beeinflußt auch die eigentlichen Komponent-Instanzen, versucht also nicht zu löschen. Wenn du nun alle Komponenten immer mit einem Owner versiehst, hast du auch ein einfaches und sauberes Speicherverhalten.

    Nichtsdestotrotz solltest du niemals OnCreate oder OnDestroy verwenden, sondern stattdessen immer Konstruktoren und Destruktoren. Begründung findest du über SuFu.

    bis bald
    akari



  • Ich möchte eine interne Verwaltung für mich einbauen, wo ich in diesem Fall sehr viele TMemos hinzufügen/löschen und modifizieren kann.

    Ich dachte eigentlich TComponentList ist genau dafür gedacht.
    TComponentList::OwnsObjects ist doch standard auf TRUE wenn man nichts sagt.
    Diese Änderung bewirkte keine Änderung.

    liste = new TComponentList;
        liste->OwnsObjects = true;
    

    Ok, ich habe mich mal an vector-Version rangetraut. Leider meldet die ebenfalls einen Fehler: In Project C:\...\Project1.exe trat ein Problem mit folgender Meldung auf: 'Zugriffsverletzung bei 0x0xd1bb45: Schreiben von Adresse 0x011b2524'. Prozess abngehalten.
    und das DEBUG(COU) Fenster öffnet sich, womit ich garnichts anfangen kann *lalala*

    Header

    private:
    vector<TComponent*> memos;
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
        TMemo *Memo = new TMemo(this);
        Memo->Visible = false;
        Memo->Parent = Form1;
        Memo->Lines->Add(TimeToStr(Time()));
    
        memos.push_back(Memo);
    
        ComboBox1->Items->Clear();
        vector<TComponent*>::iterator mIter(memos.begin());
        while (mIter != memos.end())
        {
            TMemo *M = dynamic_cast<TMemo*>(*mIter);
            ComboBox1->Items->Add(M->Text);
            ++mIter;
        }
    }
    

    Die ComboBox enhält verschiedene Zeitangaben.. soweit wohl richtig, nur mit dem fehlerfreiem Beenden will es immernoch nicht. 🙄 *jammer*



  • Ich kann auch fehlerfrei auf den vector und die dort enthaltenen Memos zugreifern

    void __fastcall TForm1::ComboBox1Change(TObject *Sender)
    {
        TMemo *mem = dynamic_cast<TMemo*>(memos.at(ComboBox1->ItemIndex));
        if (mem) Caption = mem->Text;
    }
    

    Aber wieso meckert CodeGuard beim beenden? Wenn ich CodeGuard deaktiviere läuft das Programm fehlerfrei. Ich habe keine Ahnung, kann da wer bitte Einsicht bringen? 😉

    CodeGuard

    Fehler 00001. 0x400000 (Thread 0x0D30):
    Exception 0xC0000005: Zugriffsverletzung bei 0x11B242C.
    Aufrufhierarchie:
       0x0CD1BB45(=CG32.DLL:0x01:01AB45)
       0x0CD14BE9(=CG32.DLL:0x01:013BE9)
       0x0CD142FE(=CG32.DLL:0x01:0132FE)
       0x0CD1527E(=CG32.DLL:0x01:01427E)
       0x0CD2492E(=CG32.DLL:0x01:02392E)
       0x0CD010BB(=CG32.DLL:0x01:0000BB)
    
    ------------------------------------------
    


  • Hallo

    Heinzi-kun schrieb:

    Diese Änderung bewirkte keine Änderung.

    liste = new TComponentList;
        liste->OwnsObjects = true;
    

    Du sollst es ja auch auf false setzen.

    wo ich in diesem Fall sehr viele TMemos hinzufügen/löschen und modifizieren kann...
    Ok, ich habe mich mal an vector-Version rangetraut.

    Wenn du ausschließlich TMemos in der Liste behandeln willst nimm gleich std::vector<TMemo*>. Damit ersparst du dir das ganze gecaste und auf 0 überprüfen. (Wenn in deinem vector garantiert nur gültige TMemos sind)

    Aber wieso meckert CodeGuard beim beenden? Wenn ich CodeGuard deaktiviere läuft das Programm fehlerfrei. Ich habe keine Ahnung, kann da wer bitte Einsicht bringen?

    Konkrete Probleme kann ich nun auch nicht mehr sehen. Aber ich frag mich warum du unsichtbare Memos verwendest? Warum du Memos erschaffst, deren garantiert leeren Inhalt in eine Combobox einfügst und die Memos selber "vergisst" (und auch niocht in den vector eingetragen werden) ?
    Falls das nur ein Teil der eigentlichen Routine ist, dann kann da natürlich noch ein Problem sein.

    bis bald
    akari



  • Danke für die Antwort.

    liste->OwnsObjects hatte ich auf true und false probiert. Hatte leider nichts gebracht. 😞

    Wenn du ausschließlich TMemos in der Liste behandeln willst nimm gleich std::vector<TMemo*>. Damit ersparst du dir das ganze gecaste und auf 0 überprüfen. (Wenn in deinem vector garantiert nur gültige TMemos sind)

    Ja das stimmt, aber 0 überprüfen muss doch bleiben, kann ja sein das mal ein Index irgendwo versagt und das Memo nicht mehr existiert ^^

    Warum du Memos erschaffst, deren garantiert leeren Inhalt in eine Combobox einfügst und die Memos selber "vergisst" (und auch niocht in den vector eingetragen werden)?

    Den Satz verstehe ich irgendwie nicht. Also grob gesagt habe ich eine GUI mit einem Eingabefeld(Memo) und dort tippe ich etwas rein und sage zum Beispiel "ADD" und will den Inhalt in mein vector<Memo> ablegen, später wieder aufrufen können, speichern, verschieben oder eben wieder löschen. Quasi eine kleine Verwaltung von Texten. Is nur kleiner Test. Das Prinzip brauch ich dann für etwas anderes später noch, ich taste mich so erstmal daran an.

    Also ich gehe davon aus das ich in einer Funktion ein Memo erstelle(new) und dieses dann in vector ablege mich nicht mehr um das delete kümmern muss, da der vector bei Programmende das Memo selber sauber entfernt und ich somit auf meinen vector überall im Programm zugreifen kann und meine Memos mit INhalt beleben. Ebenfalls muss ich mich beim vector selbst um kein delete kümmern da er das selber erledigt.

    Ist doch richtig oder? 🤡



  • Hallo

    Heinzi-kun schrieb:

    liste->OwnsObjects hatte ich auf true und false probiert. Hatte leider nichts gebracht. 😞

    Spricht eher dafür das CodeGuard ein Problem hat.

    Ja das stimmt, aber 0 überprüfen muss doch bleiben, kann ja sein das mal ein Index irgendwo versagt und das Memo nicht mehr existiert ^^

    Programmieren hat etwas mit Präzision und Berechnung zu tun. Ein Code wo irgendwo etwas versagt und etwas nicht mehr existiert obwohl es noch gelistet wird ist ein schlechter Code, da helfen auch Überprüfungen nichts.

    Den Satz verstehe ich irgendwie nicht. Also grob gesagt habe ich eine GUI mit einem Eingabefeld(Memo) und dort tippe ich etwas rein und sage zum Beispiel "ADD" und will den Inhalt in mein vector<Memo> ablegen, später wieder aufrufen können, speichern, verschieben oder eben wieder löschen. Quasi eine kleine Verwaltung von Texten. Is nur kleiner Test. Das Prinzip brauch ich dann für etwas anderes später noch, ich taste mich so erstmal daran an.

    Damit meine ich das Memos die nicht mehr gebraucht werden, erstens gelöscht und zweites der entsprechende Pointer aus dem vector entfernt wird. Damit ist keine weitere Übeprüfung notwendig.

    Also ich gehe davon aus das ich in einer Funktion ein Memo erstelle(new) und dieses dann in vector ablege mich nicht mehr um das delete kümmern muss, da der vector bei Programmende das Memo selber sauber entfernt und ich somit auf meinen vector überall im Programm zugreifen kann und meine Memos mit INhalt beleben. Ebenfalls muss ich mich beim vector selbst um kein delete kümmern da er das selber erledigt.

    Nein, leider hast du einen Denkfehler drin. In der Tat löscht vector selber alle seine Elemente. In deinem Fall also jeden einzelnen Pointer auf ein Memo. Aber nicht die Memos selber! Der vector löscht also nicht die Memos ansich. In deinem konkreten Fall ist das aber kein Problem da du den Memos beim erstellen einen Owner übergibst (this, also höchstwahrscheinlich das Form). Dieser ist damit fü das löschen zuständig, es entstehen also aus dieser Ecke keine Speicherlöcher. Erst wenn du als Owner NULL übergibst must du in der Tat die Memos manuell löschen. Dann machen weder vector noch Form das für dich.

    Ich weiße nochmal darauf hin das Memo eine visuelle Komponente ist. Deine Beschreibung klingt aber so als würde bei dir nichtvisuelle Komponenten wie TStringList ausreichen (weniger unnötiger Overhead)

    bis bald
    akari



  • akari schrieb:

    Nein, leider hast du einen Denkfehler drin. In der Tat löscht vector selber alle seine Elemente. In deinem Fall also jeden einzelnen Pointer auf ein Memo. Aber nicht die Memos selber! Der vector löscht also nicht die Memos ansich. In deinem konkreten Fall ist das aber kein Problem da du den Memos beim erstellen einen Owner übergibst (this, also höchstwahrscheinlich das Form). Dieser ist damit fü das löschen zuständig, es entstehen also aus dieser Ecke keine Speicherlöcher. Erst wenn du als Owner NULL übergibst must du in der Tat die Memos manuell löschen. Dann machen weder vector noch Form das für dich.

    Oha! Das schlecht, also ist wohl ComponentList->Clear() doch besser. Ich habe ja die Möglichkeit auch über Menüpunkt "Neu" ein neues Projekt zu starten, dann würde ich irgendwann ja massenhaft von Memos haben, da diese nicht entfernt würden.
    Wie lösche ich denn die Memos in <vector>"memos"?



  • Du löschst die memos mit delete bevor du sie aus dem vector entfernst. Also wenn du das Element i entfernen willst:

    vector<TMemo*> memovect;
    // irgendwelcher Code
    delete memovect[i];
    memovect.erase(memovect.begin()+i);
    

    Wenn du den vector ganz löschen willst, mußt du dein delete in einer Schleife aufrufen.



  • Das ganze löschen geht auch super mit einem Template:

    template <class T>
    class delete_it_obj
    {
    	public:
    		T operator() (T item)
    		{
    			delete item;
    			return 0;
    		}
    };
    template <template <class A> class container_type, class T> 
    void delete_it(container_type<T> &sequence) 
    { 
    	std::transform(sequence.begin(), sequence.end(), sequence.begin(), delete_it_obj<T>());
    }
    

    Quelle: http://groups.google.de/group/borland.public.cppbuilder.language/browse_thread/thread/c5c1e906e43a0f79/5a1298a953f771f2?lnk=st&q=How+to+delete+std%3A%3Avector+pointers%3F&rnum=1&hl=de#5a1298a953f771f2



  • Ich komme da irgendwie nicht mehr ganz mit. 🙄

    Ich würde gern mal zum Anfang zurückgehen, falls CodeGuard einfach nen Bug hat.
    Das mit dem TMemo, welches zur Entwicklungszeit auf die TForm gesetzt wurde verstehe ich mit dem freigeben, aber das mit der zur Laufzeit mit new angelegten nicht.

    Ich möchte beliebige Komponenten mit new erstellen und in eine Liste einfügen. Vorzugsweise TComponentList *MeineListe, da diese extra dafür gemacht wurde.
    Da die Komponenten in einer Funktion neu erstellt werden, gibt es kein delete, diese werden dann ja am Ende des Programmes mit "delete MyListe" alle entfernt.

    Im Header meiner TForm steht im

    private:
        TComponentList *MeineListe;
    

    In der Unit steht (grob, da per Hand eben getippt)

    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
        // MeineListe initalisieren
        MeineListe = new TComponentList;
    }
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        // Füge bei jedem Klick auf den Button eine
        // TImage Komponente der MeineListe hinzu
        // Auf jede TImage Komponente in MeineListe kann ich seperat zugreifen und darauf zeichnen
        // Freigabe erfolgt über "delete MeineListe" in FormClose
        TImage *MyImage = new TImage(this);
        MeineListe->Add(MyImage);
    }
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
        // Wenn (MeineListe!=NULL) dann enthält diese Komponenten
        // mit delete werden all ihre Listen(Komponenten)einträge entfernt und
        // MeineListe ebenfalls freigegeben
        if (MeineListe) delete MeineListe;
    }
    

    So habe ich es gemacht (um mal was anderes als TMemo zu nehmen, soll ja mit allem gehen). Und so müsste es doch auch fehlerfrei sein oder missverstehe ich da etwas?

    Ich kann beliebe Komponenten mit new in die TComponentList werfen und muss mich nicht um deren delete kümmern, da dieses mit "delete MeineListe" ebenfalls sauber entfernt werden.

    Ich verstehe da nicht was CodeGuard rummuckt. 🙄



  • Um bei dem Beispiel mit new TImage(this) zu bleiben... Durch das this gibst Du einen Owner an. Dieser ist für das Löschen verantwortlich. Wenn Du die TImage-Objekte aus Deiner Lister heraus löschen möchtest, darfst Du keinen Eigentümer angeben, oder mußt die Liste so anlegen, dass nur die Pointer gelöscht werden, aber nicht die Instanzen.

    In allen Projekten, die ich so gemacht habe, hatte der CodeGuard schlußendlich immer recht, auch wenn das Programm scheinbar korrekt funktionierte.



  • Mhh, um mal das für mich nachvollziehbar zu machen, bleib ich jetzt bei dem TMemo da ich jetzt die Umgebung zum testen dafür zur Hand habe.

    Ich habe also ein leeres Projekt, dort plaziere ich eine Memo zur Entwicklungszeit rein. In den Header kommt

    private:	// Anwender-Deklarationen
    TComponentList *liste;
    

    und in Unit

    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
        liste = new TComponentList;
        liste->OwnsObjects = false;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
        delete liste;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        TMemo *Memo = new TMemo(this);
        Memo->Visible = false;
        Memo->Parent = Form1;
        liste->Add(Memo);
    }
    

    Ich sage meiner TComponentList das er nicht für das löschen der Komponenten zu sorgen hat (mittels liste->OwnsObjects = false).
    Über ButtonClick füge ich eine mit new erstellte Komponente in die TComponentenList hinzu.. da es mit dies mit this passiert muss ich mich um die Löschung nicht kümmern, da dies TForm1 selbst beim beendet sauber enternt.

    Soweit schön und gut, aber wieso meckert dann CodeGuard über die Zeile "delete liste;"?
    Wenn ich das "delete liste" weg lasse .. dann meckert CodeGuard nicht und sagt alles roger. Verstehe ich nicht. Habe doch keinen Owner angegeben, also muss delete rein. 🙄



  • Zusatzfrage zur obigen.

    Ich möchte aber zwischendurch die Komponentenliste leeren, weil ich von vorn anfangen möchte. Dann wäre dies legitim?

    void __fastcall TForm1::ResetClick(TObject *Sender)
    {
        liste->OwnsObjects = true;
        liste->Clear();
        liste->OwnsObjects = false;
    }
    

    Er soll damit alle Objete in der TComponentList entfernen und die Einträge auch alle. So das ich neue Memos einfügen kann und sich während der Arbeit mit dem Programm nicht im Hinterfrund plötzlich hunderte nicht benutzte Memos ansammeln. 😉

    CodeGuard meldet zwar keinen Fehler, aber das muss ja nicht heissen das es richtig ist.



  • Hallo

    Heinzi-kun schrieb:

    Ich habe also ein leeres Projekt, dort plaziere ich eine Memo zur Entwicklungszeit rein. In den Header kommt
    ...
    Wenn ich das "delete liste" weg lasse .. dann meckert CodeGuard nicht und sagt alles roger. Verstehe ich nicht. Habe doch keinen Owner angegeben, also muss delete rein. 🙄

    Du verwendest OnCreate und OnClose. Damit hast du schon mal ein Problem, denn die beiden Events gehören nicht zusammen. Die korrekten Paare sind OnCreate/OnDestroy und OnShow/OnClose. Bei dir wäre theoretisch der Ablauf denkbar
    - Instanz des Forms wird erstellt : Aufruf von OnCreate, Liste wird erstellt
    - Instanz wird angezeigt : Aufruf von OnShow
    - Form wird geschlossen : Aufruf von OnClose, Liste wird gelöscht
    - Form wird wieder angezeigt : Aufruf von OnShow, Zugriff auf Liste... Zugriffsfehler

    Das tritt bei dir so nicht auf weil dein Form das Hauptformular ist und beim Schließen gleich die Anwendung beenden. Darauf darfst du dich aber nicht verlassen. Denk immer dran : Ein geschlossenes (nicht sichtbares) Form heißt noch lange nicht das es wirklich gelöscht wird oder das die Anwendung beenden wird.
    Kann schon sein das CodeGuard dieses Problem sieht trotz das es praktisch bei dir nicht ausgelöst wird.

    Übrigens ein weiter Grund OnCreate und OnDestroy nicht zu benutzen : Verwechslungsgefahr mit OnShow/OnClose.

    ch möchte aber zwischendurch die Komponentenliste leeren, weil ich von vorn anfangen möchte. Dann wäre dies legitim?...

    Sollte in Ordnung sein.

    bis bald
    akari



  • Danke für deine umfangreiche Antwort!

    Das mit Create/Destroy und Show/Close behalte ich im Hinterkopf, habe es mal entsprechend geändert.

    Bleibt aber die Frage warum muss ich kein "delete liste" ausführen?
    In diesem Fall ist es egal ob es im Close oder Destroy steht, der Fehler bleibt der Selbe.

    Wenn ich Create nicht benutzen sollte, dann soll ich das direkt ins "__fastcall TForm1(TComponent* Owner);" eintragen?

    Es existiert aber kein Destructor in der TForm1 Klasse. Der wird wohl in der abgeleiteten TForm Klasse liegen.
    Muss ich jetzt VCL korrekt ein "__fastcall ~TForm1();" einfügen und dort meine Freigaben tätigen, oder wie sonst? 🤡



  • Hallo

    Bleibt aber die Frage warum muss ich kein "delete liste" ausführen?
    In diesem Fall ist es egal ob es im Close oder Destroy steht, der Fehler bleibt der Selbe.

    Ich kann das Verhalten nicht nachvollziehen. Auf meinem BCB5 habe ich dein Test ausprobiert und folgendes festgestellt :
    - Ohne CodeGuard kommen keine Probleme
    - Mit CodeGuard wird egal ob OnDestroy oder Destruktor bei delete liste eine Speicherzugriffsverletzung angezeigt, aber nur wenn ein Memo in die liste eingetragen wurde.
    Das deutet eher auf ein internes Problem CodeGuard/VCL hin.

    Wenn ich Create nicht benutzen sollte, dann soll ich das direkt ins "__fastcall TForm1(TComponent* Owner);" eintragen?

    In die Implementation des Konstruktors, ja.

    Es existiert aber kein Destructor in der TForm1 Klasse. Der wird wohl in der abgeleiteten TForm Klasse liegen.
    Muss ich jetzt VCL korrekt ein "__fastcall ~TForm1();" einfügen und dort meine Freigaben tätigen, oder wie sonst? 🤡

    Ja, der Destrukor muß manuell hinzugefügt werden.

    bis bald
    akari



  • Ah, danke!
    Also muss das delete liste; wieder rein und muss mir wegen des Fehlers von CodeGuard keine gedanken machen. 😉



  • Ja, doch. In deinem ersten Post hast Du die Fehlermeldungen mit angegeben. Dort war das Problem definitiv, dass die Objekte die freigegeben werden sollten, zu diesem Zeitpunkt bereits freigegeben waren.


Anmelden zum Antworten