Also jetzt bin ich verwirrt...(Array, StringList, Vector...)
-
Vorweg: Ich lese mich heut schon den ganzen Tag hier durch das Forum, auch das FAQ. Auch durch die BCB-Hilfe bin ich nicht schlauer geworden.
Ich überlege, wie ich mehrdimensional Strings abspeichern bzw. verwalten kann. Dazu bräuchte ich also so eine Art Stringlist-Array. Von normalen Arrays wurde an verschiedenen Stellen hier im Forum abgeraten, und durch meine Lektüre habe ich den Eindruck bekommen, dass man in Vektoren nur Zahlen speichert/speichern kann. Bis jetzt habe ich einfach immer eine Stringlist verwendet wenn es ums Speichern/Verwalten von Strings ging. Aber ich habe nirgendswo einen Hinweis dazu gefunden, bzw. bin nicht in der Lage dazu, von einer Stringliste ein Array zu erstellen.
BTW, wieviel Speicher verbraucht eigentlich so eine Stringlist? Pro Eintrag soviel Speicher wie ein AnsiString? (Ich weiß, sind jetzt zwei Fragen - man möge mir verzeihen)
-
TStringList *StrLArr[64];
z.B. so...
oder:String mDimStrArr[64][64];
Aber letzteres sagt dir ja offensichtlich nicht zu...
-
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 = genauwie 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).