Also jetzt bin ich verwirrt...(Array, StringList, Vector...)



  • Dann lieber :

    vector<TStringList*> MultiStringList;



  • Ok, ich habe mich mittlerweile dazu entschlossen, ein DynamicArray einer selbstgeschriebenen Klasse zu erstellen. Die Klasse heißt User, und beinhaltet lediglich drei private Werte und die public Methoden zum Verändern bzw. Auslesen dieser drei Werte. Die Klasse funktioniert. Leider stürzt mein Programm ab, wenn ich versuche mit dem DynamicArray zu arbeiten (es kommt also keine Fehlermeldung, sondern das Programm bricht mit "Diese Anwendung wird aufgrund eines ungültigen Vorgangs..." ab).

    ushort iUSERCOUNT = lv_USER->Items->Count; // ushort ist ein typedef von unsigned short int
    DynamicArray<User*> RecUser; // User ist die Klasse
    RecUser.Length = iUSERCOUNT;
    
    // Empfängername + Empfängerorder (verschicken ja/nein?) in Klassenarray aufzeichnen
    for (ushort i = 0; i < iUSERCOUNT; i++)
    {
       RecUser[i] = new User; //diese Zeile habe ich testweise auch mal weggelassen
       RecUser[i]->SetName(lv_USER->Items->Item[i]->Caption);
       RecUser[i]->SetOrder(lv_USER->Items->Item[i]->Checked);
       RecUser[i]->SetStatus(true);
    }
    
    // ...weiterer Code...
    
    // Speicher des Klassenarrays wieder freigeben
    RecUser.Length = 0;
    

    Leider kann ich den Fehler nicht lokalisieren. Aber irgendwas muss ich wahrscheinlich mit der Deklaration oder der Größenzuweisung des DynamicArray falsch machen. 😕 Wäre für jede Hilfe dankbar.



  • hi,

    // Speicher des Klassenarrays wieder freigeben
    RecUser.Length = 0;

    falsch ! Damit wird nur der vom Array reservierter Speicherplatz freigegeben. Nicht der Speicherplatz der User- Instanzen.

    Die Folge- > Speicherlöcher



  • Ok, aber ist das der Grund für den Absturz des Programms?

    Edit: PS: Wie gibt man den Speicher der User-Instanzen wieder frei?



  • Regel nummer 1:
    Auf jedes new muss irgendwo ein delete folgen...

    -junix



  • Ahja und was den Absturz betrifft: Kannst du den Absturz genau provozieren? Dann benutz mal den Debugger um die genaue Fehlerzeile festzustellen...

    -junix



  • Zur Regel Nr. 1: Geht das so?

    // Speicher des Klassenarrays wieder freigeben
    for (ushort i = 0; i < RecUser.Length; i++)
       delete RecUser[i];
    RecUser.Length = 0;
    

    Zu dem Absturz: Ich hab die "böse" Stelle mit einigen Haltepunkten ausfindig machen können.

    ushort iUSERCOUNT = lv_USER->Items->Count;
    DynamicArray<User*> RecUser; 
    RecUser.Length = iUSERCOUNT;
    
    for (ushort i = 0; i < iUSERCOUNT; i++)
    {
       RecUser[i] = new User;
       // Folgende Zeile verursacht Programmabsturz
       RecUser[i]->SetName(lv_USER->Items->Item[i]->Caption); 
       // Folgende Zeile verursacht Programmabbruch wegen Speicherverletzung
       // im Modul VCL60.BPL
       RecUser[i]->SetOrder(lv_USER->Items->Item[i]->Checked);
       // Folgende Zeile verursacht dasselbe wie die letzte Anweisung
       RecUser[i]->SetStatus(true);
    }
    

    Ich befürchte, dass es vielleicht doch an der Klasse liegen könnte, also:

    class User
    {
       public:
          User() { itsName = ""; itsStatus = false; itsOrder = false; }; // Standardkonstruktor
          ~User();	// Destruktor
    
          void        SetName(const AnsiString Name);
          AnsiString  GetName()   const;
          void        SetStatus(const bool Status);
          bool        GetStatus() const;
          void	    SetOrder(const bool Order);
          bool	    GetOrder() 	const;
    
       private:
          AnsiString itsName;
          bool itsStatus;
          bool itsOrder;
    };
    
    User::~User()
    {}
    
    void User::SetName(const AnsiString Name)
    {
       itsName = Name;
    }
    
    AnsiString User::GetName() const
    {
       return itsName;
    }
    
    void User::SetStatus(const bool Status)
    {
       itsStatus = Status;
    }
    
    bool User::GetStatus() const
    {
       return itsStatus;
    }
    
    void User::SetOrder(const bool Order)
    {
       itsOrder = Order;
    }
    
    bool User::GetOrder() const
    {
       return itsOrder;
    }
    


  • Frage:

    Beim Fehlerer -> wie groß ist i und wie groß ist RecUser.Count ?



  • Ich weiß nicht genau, was du mit RecUser.Count meinst? i wächst ja mit jedem Schleifendurchgang um eins. i Beginnt bei null und wird maximal so groß wie es RecUser-Instanzen (abzüglich 1) gibt.

    Ich habe die Klasse - wenn auch widerwillig - gegen ein struct ausgetauscht. Es gibt jetzt keine Fehler mehr. Naja aber das ist ja nicht der Sinn der Sache. Ich hätte schon gern rausgefunden, wo sich das kleine Teufelchen versteckt hat.

    struct User
    {
    	AnsiString Name;
    	bool Order;
    	bool Status;
    };
    
    ushort iUSERCOUNT = lv_USER->Items->Count; // Anzahl der User insgesammt
    DynamicArray<User*> ur; // Dynamisches Array der Struktur User erstellen
    ur.Length = iUSERCOUNT;
    try
    {
    	   // Empfängername + Empfängerorder (verschicken ja/nein?) in Klassenarray aufzeichnen
       	for (ushort i = 0; i < iUSERCOUNT; i++)
             {
                ur[i] = new User;
                ur[i]->Name 	= lv_USER->Items->Item[i]->Caption;
                ur[i]->Order 	= lv_USER->Items->Item[i]->Checked;
                ur[i]->Status	= true;
    	}
             // .....weiterer code
    }
    __finally
    {
       	// Speicher des Struct-Arrays wieder freigeben
             for (ushort i = 0; i < ur.Length; i++)
       	{
    	   	delete ur[i];
    	         ur[i] = 0;
       	}
             ur.Length = 0;
    }
    


  • Frage: Hast du den von mir verlinkten artikel sowie dessen verlinkten Artikel gelesen und die darin enthaltenen Ratschläge befolgt? Macht nicht den Eindruck, wenn du nîcht gneau weisst, worauf andreas raus wollte...

    -junix

    [edit]Ausserdem ist doch deine feststellung, dass mit einem Struct alles funktioniert ein wunderbarer Hinweis wo du mit der Fehlersuche ansetzten solltest?[/edit]



  • @ junix.

    würdest du bitte, bevor du auf -absenden- drückt, deine beiträge genau durchlesen?
    gneau = genau

    wie du mir, so sich dir 😡



  • Ok, richtig zu debuggen ist wichtig. Also werde ich mir euer "Standardwerk" durchlesen. Danke für die Hilfe.

    Edit: @junix: Das habe ich ja bereits weiter oben schon in Verdacht gehabt 😉



  • Bj schrieb:

    wie du mir, so sich dir 😡

    naja, nicht ganz. Ein Buchstabendreher auf diese Zeichenzahl... wenn ich da die von mir beanstandeten Beiträge von dir anschaue...

    -junix



  • Bomania schrieb:

    [...]Also werde ich mir euer "Standardwerk" durchlesen. Danke für die Hilfe.

    Hmmmmm normalerweise setz ich meine Links nicht nur zum Spass, sondern dass man sie auch schon beim ersten Auftauchen zumindest mal beschnuppert... so für s'nächste mal (o;

    -junix



  • Ja, das mit deinen Links ist mir schon in vielen Threads aufgefallen. Da du das Wort "Debugging" verlinkt hast, konnte ich ja nicht wissen, dass sich das direkt auf das .Count beziehen soll. Sah eher so aus, als ob das als zusätzliche Hilfe fürs Debuggen gedacht war (ist ja auch der Fall, aber wie gesagt - Zusammenhang war für mich nicht klar).


Anmelden zum Antworten