AccessViolation beim DynamicArray für TLabel
-
Ich versuche Label mit einem DynamicArray zu erzeugen, erhalte jedoch eine AccessViolation und hab kein plan wieso.[cpp]UserLabels.Length++; //DynArray Länge incrementiern
UserLabels[UserLabels.Length-1] = new TLabel(this); //Neues Label hinzufügen
UserLabels[UserLabels.Length-1]->Caption = Socket->RemoteHost;
UserLabels[UserLabels.Length-1]->Font->Color = clRed;
UserLabels[UserLabels.Length-1]->Parent = UserScrollBox;
if(UserLabels.Length == 1) //positionieren
{
UserLabels[UserLabels.Length-1]->Top = 5;
}
else
{
UserLabels[UserLabels.Length-1]->Top =
UserLabels[UserLabels.Length-2]->Top +
UserLabels[UserLabels.Length-2]->Height + 3;
}
UserLabels[UserLabels.Length-1]->Left = 5;
UserLabels[UserLabels.Length-1]->Visible = true; [/cpp]Der Debugger bleit bei der fett markierten Zeile stehen.
-
Schrecklicher Code.
-
Das hilft mir nicht gerade weiter, könntest du mir sage, was daran so schrecklich ist, und was ich tun muss, damit es geht?
-
Die Ursache für das Problem muss an anderer Stelle im Code liegen, der hier gezeigte Abschnitt ist soweit in Ordnung.
-
An dieser Stelle hätte ich jetzt mal eine Frage:
Wenn ich stattUserLabels[UserLabels.Length-1] = new TLabel(this); //Neues Label hinzufügen UserLabels[UserLabels.Length-1]->Caption = Socket->RemoteHost; //[...]schreibe
TLabel* Lbl = new TLabel(this); UserLabels[UserLabels.Length-1] = Lbl; Lbl->Caption = Socket->RemoteHost; //[...]Ist das dann im Zugriff schneller als die erste Version? Ich muss ja nicht jedesmal aus dem Array den entsprechenden Eintrag "raussuchen", sonder gebe die Adresse direkt an?
Oder tut sich das nicht viel, da das ein Unterschied von villeicht 3 Befehlen oder so ist?Ich benutze bisher immer die Letzte Variante, allein desshalb, weils weniger zu tippen ist. Es würde mich aber trotzdem mal interessieren, ob der Zugriff über den Index "viel oder wenig" Zeit beansprucht.
-
Hallo
Ist das dann im Zugriff schneller als die erste Version? Ich muss ja nicht jedesmal aus dem Array den entsprechenden Eintrag "raussuchen", sonder gebe die Adresse direkt an?
Oder tut sich das nicht viel, da das ein Unterschied von villeicht 3 Befehlen oder so ist?Das zweite ist schon schneller. Allerdings nur ein paar Takte, denn Arrays sind so aufgebaut, das Zugriffe mit schneller Speicherarithmetik erfolgen können, im Gegensatz zu Listen, wo alle vorliegenden Elemente durchlaufen werden müßen.
Die zweite Variante halte ich einfach für eleganter.
bis bald
akari
-
Ich bin dabei eine Client Server Anwendung zu schreiben. Der Code ist Teil des OnClientConnect Events. Dies ist auch die einzige Stelle, bei der ich das DynArray verwende. Ich habe jetzt auch mal die Variante von =]xXx[=- verwendet, komischer weise gehts jetzt. Natürlich habe ich nichts dagegen, dass es jetzt funktioniert, ich möchtet trotzdem gärne wissen, weshalb es vorhin nicht ging.
Hier ist mal der ganze OnClientConnect Event:void __fastcall TMainForm::ServerSocketClientConnect(TObject *Sender, TCustomWinSocket *Socket) { int Size; TLabel* TempLabel = new TLabel(this); //TempLabel für DynArray if(SearchUser(Socket->RemoteHost) < 0) //neuer User { Size = User.Length; User.Length++; User[Size]->Name = Socket->RemoteHost; User[Size]->State = NewUserState; User[Size]->Connectet = false; } if(User[SearchUser(Socket->RemoteHost)]->Connectet) //Überprüfen, ob User bereits connectet { Socket->SendText(AllreadyConnectetMessage); //Fehlermeldung an Client senden Socket->Disconnect(Socket->SocketHandle); //Verbindung zu Client trennen } else { TempLabel->Caption = Socket->RemoteHost; //Name des Client TempLabel->Font->Color = clRed; //Textfarbe rot TempLabel->Parent = UserScrollBox; if(UserLabels.Length <= 1) //positionieren { TempLabel->Top = 5; } else { TempLabel->Top = UserLabels[Size-1]->Top + TempLabel->Height + 3; } TempLabel->Left = 5; TempLabel->Visible = true; //Anzeigen UserLabels.Length++; //DynArray Länge incrementiern UserLabels[UserLabels.Length-1] = TempLabel; //Neues Label hinzufügen Socket->SendText(SendPasswordMessage); //Passwort anfordern } }Ich hab da jetzt noch ne andere Frage. Ich erstelle ja jetzt ein temporäres Label um die elegantere Variante zu nutzen. Sollte ich dies nicht vor beenden des Events wieder deleten? Bloss wenn ich das mache, wird es nicht angezeigt. Ha da glaubs etwas noch nicht so ganz verstanden.
-
wedmer schrieb:
Ich erstelle ja jetzt ein temporäres Label
Nein. Du erstellst einen temporären Zeiger auf ein Label.
Gruß,
Alexander
-
Ja ok, hast recht es ist ein Zeiger. Aber trotzdem sollte ich doch den Speicher, den ich für das Label reserviere wieder frei geben, oder nicht? Bin verwirrt. Mit der Zeile
TLabel* TempLabel = new TLabel(this);erstelle ich doch ein Zeiger TempLabel auf den Speicher, den ich mit new TLabel(this) reserviere, oder? Und den sollte ich doch am Ende es Events wieder frei geben, oder? Nur wie? Wenn ich einfach ein delete TempLabel; am Schluss schreibe, wird das Label nicht angezeigt.
-
schritt 1: du erstellst einen zeiger auf ein TLabel (TempLabel)
schritt 2: du reservierst speicher für das TLabel
Schritt 3: du übergibst den Zeiger(die Speicheradresse) an UserLabels.
-
Danke, jetzt hab ichs auch kapiert. hmm, ich sollte glaubs mal wieder etwas mehr schalfen...