EAccessViolation bei ListBox->Items->Add [gelöst]



  • Hallo Gemeinschaft,

    dies ist die Fortsetzung eines anderen Thema's, welches im Nachhinein als Fehlersuche zu bewerten ist (hier). Und hier das Problem: Ich bekomme einen Zugriffsfehler , wenn ich eine ListBox mit Werten füllen will. Hier mal ein Beispiel für das Füllen der ListBox in einer Button-Klick-Methode, wie es bei mir einen Fehler verursacht:

    void __fastcall TFormNewEACfg::Button1Click(TObject *Sender)
    {
        for(int Idx=0; Idx<18; Idx++)
        {
            Eintrag= Wert[0][Idx];
            Eintrag.Delete(Eintrag.LastDelimiter("~"),2);
            this->LstBxGet->Items->Add(Eintrag);   // ZugriffsFehler !!!
        }
    }
    

    Der Aufruf, welcher den Zugriffsfehler verursacht, ist mit einem Kommentar versehen. Die Variablen: Wert[][] ist ein const AnsiString-Array gefüllt mit Strings, die alle am Ende "~<Steuerzeichen>" (2 Zeichen) enthalten. Eintrag ist eine private-Variable, ebenfalls ein AnsiString.

    Was habe ich versucht: Ich habe die ListBox gelöscht und nochmal neu auf das Formular gelegt. Ich habe das gesamte Formular nochmal neu erstellt. Ich habe das Füllen der ListBox aus dem Konstruktur in eine Button-Klick-Methode verlegt.
    Ich hatte die beiden Anweisungen vor Add (siehe Beispiel) in einer Funktion, die ich aus der Schleife aufrufen ließ. Diese Funktion habe ich wegrationalisiert.
    Es half Alles nichts, ich bekomme immer einen Zugriffsfehler in BCB3 beim Add.
    Was gibt es für Möglichkeiten dafür, dass diese Anweisung einen Zugriffsfehler verursacht?

    Edit: Auch die 2. ListBox auf dem Formular lässt sich nicht mit neuen Einträgen versehen. 😞



  • Das heißt, du bekommst auch Fehler, wenn du einfach

    LstBxGet->Items->Add ("some_string");
    

    schreibst?

    Tritt das auch in neu erstellten Anwendungen auf?
    Ansonsten verfolge mal den Call-Stack bis zum Auftreten der Exception (ich weiß allerdings nicht, ob C++Builder 3 schon über so etwas verfügte).





  • Den Link habe ich doch oben schon gepostet Braunstein. 😉

    audacia schrieb:

    Das heißt, du bekommst auch Fehler, wenn du einfach

    LstBxGet->Items->Add ("some_string");
    

    schreibst?

    Ja!

    audacia schrieb:

    Tritt das auch in neu erstellten Anwendungen auf?

    Ich möchte meinen, ja. Aber ich erstelle sicherheitshalber gleich nochmal ein neues Projekt zum Testen.

    audacia schrieb:

    Ansonsten verfolge mal den Call-Stack bis zum Auftreten der Exception (ich weiß allerdings nicht, ob C++Builder 3 schon über so etwas verfügte).

    Ja, hat Builder 3 schon. Ich kann den call-stack bei der exception nochmal posten, wenn sie im neuen Projekt wieder auftritt.



  • Kolumbus schrieb:

    Den Link habe ich doch oben schon gepostet Braunstein. 😉

    Hatte ich wohl übersehen. 🙂
    Ich hab das nur nochmal geschrieben, weil audacia nach dem Callstack fragte.
    Joe hat dein projekt ja schon auf dem BCB6 zum Laufen gebracht. Es könnte also sein, dass es an deinem BCB3 liegt. Den habe ich bei mir aber auch nicht mehr drauf. Ich könnte maximal noch einen BCB5 bieten. 🙂



  • Ich habe jetzt nochmal ein neues Projekt erstellt:
    * Datei->Neu...->Projektgruppe
    * Projektgruppe als "TestGruppe" in neuem Ordner gespeichert
    * Datei->Neu...->Anwendung
    * Unit1 entfernt
    * Projekt als "TestProjekt" in selben Ordner wie TestGruppe gespeichert
    * Unterordner "SRC" erstellt
    * *.cpp, *.h und *.dfm von 3 Formularen aus altem Projekt in SRC kopiert
    (Main, Nebenformular und Problemformular)
    * Formulare zum Projekt hinzugefügt (werden beim Programmstart erzeugt)
    * Im MainForm gibts lediglich eine MainMenu-Komponente mit 2 Menüpunkten:
    1. Nebenformular->ShowModal();
    2. Problemformular->ShowModal();
    ----------
    * Projekt erstellt (erstmal ohne Debugger)
    * Projekt gestartet -> Problemformular angezeigt -> Button "Liste füllen" gedrückt -> AccessViolation !!!
    ----------
    * Projekt erstellt (mit Debugger: Projekt->Optionen->CompilerOptionen->voll debuggen)
    * Haltepunkt bei Problemformular->ListBox->Items->Add-Anweisung gesetzt
    * Projekt gestartet -> Problemformular angezeigt -> Button "Liste füllen" gedrückt -> Bild 1
    * F7 gedrückt -> Bild 2
    * Ok gedrückt und CallStack angezeigt -> Bild 3
    ----------

    Wenn ich this weglasse und einen String angebe passiert dasselbe, wie beschrieben.

    LstBxGet->Items->Add("Test");   // ZugriffsFehler !!!
    

    ----------

    Braunstein schrieb:

    Es könnte also sein, dass es an deinem BCB3 liegt.

    Was bedeutet das für mich?



  • Hallo

    Ich interpretiere das als Ratschlag das du dir eine aktuellere Builder-Version zulegen solltest, und sei es nur die auch schon mehrere Jahre alte 6er aus Restbeständen.

    bis bald
    akari



  • @akari: Ich intepretiere deine Antwort mal so: Du hast mitgelesen und bist auch der Meinung, dass keine Fehler zu finden sind und es eigentlich so funktionieren müsste!?!

    Allgemein zu meiner Benutzung des BCB3: Ich suche mir nicht aus, mit welcher IDE ich hier arbeite. Ich habe zwar das BDS2006 zur Verfügung, kann aber darin keine Projekte erstellen, da es im Hause keinen InstallShield-Creator gibt, der mit BDS2006-Projekten klarkommt. Zu allem Übel sind die verantwortlichen Kollegen der Meinung, ein neuer InstallShield-Creator wäre zu teuer... Also muss ich die Projekte im Endeffekt im BCB3 machen. 😞



  • Hallo

    Kolumbus schrieb:

    @akari: Ich intepretiere deine Antwort mal so: Du hast mitgelesen und bist auch der Meinung, dass keine Fehler zu finden sind und es eigentlich so funktionieren müsste!?!

    Seit meinem letzten Post im altem Thread habe ich keine weiteren Ideen zu Fehlerursachen. Da es im BCB6 läuft schiebe ich die Ursache auf den BCB3.

    bis bald
    akari



  • Kolumbus schrieb:

    Ich habe jetzt nochmal ein neues Projekt erstellt[...]

    Das ist aber kein neues Projekt, weil Du ja Dateien, aus einem anderen Projekt
    hineinkopierst.
    Wenn Du ein neues Projekt erstellst, eine ListBox draufknallst und dann z.B.
    in einem Button-Ereignis einen Eintrag hinzufügst, funktioniert es dann?

    Gruß

    Alexander



  • Desweiteren gibt es ja noch andere (kostenfreie) Installer. z.Bsp. InnoSetup, der kann auch InstallShield-Scripte importieren. So das der Installshield ja kein Grund sein kann nicht zu wechseln.



  • Alexander Kempf schrieb:

    Kolumbus schrieb:

    Ich habe jetzt nochmal ein neues Projekt erstellt[...]

    Das ist aber kein neues Projekt, weil Du ja Dateien, aus einem anderen Projekt
    hineinkopierst.
    Wenn Du ein neues Projekt erstellst, eine ListBox draufknallst und dann z.B.
    in einem Button-Ereignis einen Eintrag hinzufügst, funktioniert es dann?

    Nein. AccessViolation bei ListBox->Items->Add("Test"); .

    Interessant ist: in allen Projekten, in denen Add nicht funktioniert, wird immer dieselbe Adresse angesprungen wird (siehe Bild 2 weiter oben)... Sieht da jemand einen Hinweis?

    Braunstein schrieb:

    Desweiteren gibt es ja noch andere (kostenfreie) Installer. z.Bsp. InnoSetup, der kann auch InstallShield-Scripte importieren. So das der Installshield ja kein Grund sein kann nicht zu wechseln.

    Ich kenn mich dahingehend garnicht aus - gibt es auch kostenfreie Installer, die kommerziell genutzt werden dürfen?



  • Hallo

    Das unter gleichen Umständen auch immer die gleichen Adressen verwendet werden ist üblichen.

    Innosetup ist auch kommerziell kostenfrei einsetzbar.

    bis bald
    akari



  • akari schrieb:

    Das unter gleichen Umständen auch immer die gleichen Adressen verwendet werden ist üblichen.

    Schade... wär ja auch zu schön, den Fehler greifen zu können.... 😞

    akari schrieb:

    Innosetup ist auch kommerziell kostenfrei einsetzbar.

    Danke für den Link! 🙂



  • Hm, schon mal getestet, ob der Rechner einfach einen Weg hat? Defekter RAM?



  • Hmm.. nö, wie mach ich das jetzt am Schnellsten?

    Edit: Ach Quatsch... kann ich mir ja sparen... im Ursprungsprojekt funktioniert ja ListBox-Items->Add noch!!!



  • Ich weigere mich immernoch zu glauben, dass etwas Grundlegendes mit dem BCB3 nicht stimmt (außer das er alt ist). Deswegen habe ich jetzt nochmal das Projekt geöffnet, wo ich das 1.Mal mit ListBoxen und ListBox->Items->Add gearbeitet habe.
    Dort habe ich auf dem Formular mit den vorhandenen ListBoxen eine neue ListBox und einen Button mit Klick-Methode hinzuzugefügt. In die Klick-Methode habe ich geschrieben:

    ListBox3->Items->Add("Eintrag " + IntToStr(EntryNr));
    EntryNr++;
    

    wobei EntryNr im Header unter private als int EntryNr; deklariert wurde. Im Konstruktor des Forms setzte ich EntryNr= 0;
    Wenn ich das Programm starte, das Formular anzeige und auf den Button klicke, wird "Eintrag 0" in die ListBox3 eingefügt (angezeigt). Beim nächsten Klick kommt "Eintrag 1" dazu usw.
    Es funktioniert also noch - aber warum nicht, wenn ich ein neues Projekt erstelle? 😕



  • Kannst du mir dein Projekt auch mal schicken. Ich würde das auch mal gerne ausprobieren. Allerdings mit dem BCB5.



  • Es funktioniert wieder!!! 😃 🙂 😃 🙂 😃 🙂 😃 🙂 😃 🙂

    Ich habe das alte Projekt (ListBox->Items->Add() funktionierte) und das neue Projekt (das letzte Testprojekt, nur mit Button und ListBox) gleichzeitig geöffnet (2x BCB3 offen) und mir Alles so hingeschoben, dass ich bequem die Projektoptionen von beiden Projekten vergleichen konnte. Dann habe ich alle Einstellungen vom alten Projekt, die sich zum Testprojekt unterschieden, für das Testprojekt übernommen.

    Folgende Einstellungen im Testprojekt waren unterschiedlich:
    (ich liste alle Unterschiedlichen auf, auch wenn ich von Einigen schon weiß, dass sie nicht verantwortlich für den Fehler sein dürften.)
    Ich schreibe hinter ***** die Einstellung im Testprojekt und hinter # die geänderte Einstellung (aus dem alten Projekt übernommen).

    /*
     Compiler-Optionen -> * Endgültige Version
                       -> # voll debuggen
    */
     erweiterte Compiler-Optionen -> Datenausrichtung -> * QuadWord
                                                      -> # DoubleWord
    
     erweiterte Compiler-Optionen -> Gleitkomma -> Schnell -> * Häkchen gesetzt
                                                           -> # Häkchen entfernt
    
     Pascal -> Syntaxoptionen -> Boolsche Ausdrücke vollständig -> * Häkchen gesetzt
                                                                -> # Häkchen entfernt
    
     Pascal -> Syntaxoptionen -> Zuweisbare typisierte Konstanten -> * Häkchen entfernt
                                                                  -> * Häkchen gesetzt
    /*
     Pascal -> Meldungen -> * Alle Meldungen
                         -> # keine Meldungen
    
     Linker -> dynam. RTL verwenden -> * Häkchen entfernt
                                    -> # Häkchen gesetzt
    
     Verzeichnisse / Bedingungen -> Bedingungen -> Definition: -> * leer
                                                               -> # _RTLDLL;USEPACKAGES
    
     Packages -> Laufzeit-Packages -> mit Laufzeit-Packages compilieren -> * Häkchen entfernt
                                                                        -> # Häkchen gesetzt
    */
    

    Ich mach jetzt Feierabend, schaue aber Zuhaus nochmal hier rein... Vielleicht kann ja spontan jemand sagen, an welcher Einstellung es lag und WARUM!?

    @ Braunstein: Danke für das Angebot. Erübrigt sich ja nun.

    Edit: ich kommentiere mal die Einstellungen aus, die ich für nicht relevant halte. Die Anderen teste ich jetzt und versuche herauszufinden, was sie beeinflussen.



  • Gut, es lag wohl an der Einstellung für die Datenausrichtung in den erweiterten Compiler-Optionen. Die Hilfe schreibt dazu:

    Die Optionen Datenausrichtung erlauben, auszuwählen wie der Compiler Daten im Speicher ausrichtet. Word-, Double-Word- und Quad-Word-Ausrichtung zwingen den Compiler Objekte von Integer-Größe (und größer) so auf die Speicheradressen auszurichten, daß die Startadressen immer ein Vielfaches von dem gewählten Typ sind. Es werden zusätzliche Bytes in Strukturen eingefügt, um sicherzustellen, daß Elemente korrekt ausgerichtet sind.

    Vorgabe = Double Word (32-Bit)

    Byte richtet auf 8-Bit-Grenzen aus.
    Word richtet auf 16-Bit-Grenzen aus.
    Double Word richtet auf 32-Bit-Grenzen aus.
    Quad Word richtet auf 64-Bit-Grenzen aus.

    Kann jemand erklären, warum es bei ListBox->Items->Add() zu der Zugriffsverletzung kommt, wenn die Datenausrichtung auf QuadWord gestellt ist?
    So ganz klar ist mir das nämlich nicht. Ich wäre der Meinung, dass diese Einstellung auf QuadWord lediglich dazu führt das für das Programm mehr Speicher gebraucht wird!?


Log in to reply