Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi erstes Element aus dynamischem Array löschen (https://www.delphipraxis.net/52776-erstes-element-aus-dynamischem-array-loeschen.html)

TheAn00bis 3. Sep 2005 14:46


erstes Element aus dynamischem Array löschen
 
Hi, ich habe schon die suche benutzt und auch den Eintrag in der Code-Libary gefunden, allerdings habe ich keine Ahnung von Pointern und Assembler, von daher wollte ich lieber meine eigene Procedur schreiben.

Allerdings scheint die follgende immer eine "Invalid Pointer Message" oder eine AV zu erzeugen. Könnte jemand mal drüber schauen?

Achja, es kommt auf die Reihenfolge an, ich will nur das erste Element löschen und den Rest nachrücken lassen und es soll keine allgemeine Procedure sein, sondern nur auf das dyn Array "Zeiten" zugreifen

Delphi-Quellcode:
procedure TMain.loesche;
var n,t,y:integer;
begin
for n:=length(zeiten) downto 0 do begin
 if n<>0
    then begin
         t:=zeiten[n];
         zeiten[n-1]:=t;
    end;
 end;

y:=length(zeiten);
setlength(zeiten,y-1)
end;

Mr_G 3. Sep 2005 14:53

Re: erstes Element aus dynamischem Array löschen
 
Ich würde es glaueb ich so machen:
Delphi-Quellcode:
procedure TMain.loesche;
var i,l: Integer;
begin
for i := 0 to length(zeiten) do
  zeiten [i] := zeiten[i +1];

l:=length(zeiten);
setlength(zeiten,l-1);
end;
... ungetestet ...

TheAn00bis 3. Sep 2005 14:58

Re: erstes Element aus dynamischem Array löschen
 
Danke, hast Recht, ist um einiges unkomplizierter. Hab es getestet und scheint keinen Unterschied zu machen.

Und du bist sicher, dass man einfach die Länge ändern darf? Also obwohl das letzte Element dann irgendwo verschwindet? Oder muss man erst den Speicher freigeben oder so?

Mr_G 3. Sep 2005 15:10

Re: erstes Element aus dynamischem Array löschen
 
Also sicher bin ich mir da nicht. Aber spontan würde ich sagen der Speicher des letzen Elementes wird damit wieder freigegeben bzw. nicht mehr reserviert. Und von daher sollte das doch in Ordnung sein, oder?

P.S.: Klappts denn wenigstens?

brechi 3. Sep 2005 15:12

Re: erstes Element aus dynamischem Array löschen
 
Mr_G muss auch noch nen -1 hin sonst greift man auf ein element zu weit zu

Christian Seehase 3. Sep 2005 15:14

Re: erstes Element aus dynamischem Array löschen
 
Moin Zusammen,

statt

Delphi-Quellcode:
for i := 0 to length(zeiten) do
muss es aber

Delphi-Quellcode:
for i := 0 to length(zeiten)-1 do
// oder
for i := 0 to high(zeiten) do
heissen, da ansonsten

Delphi-Quellcode:
zeiten [i] := zeiten[i +1];
beim letzten Element schiefgeht.

Was ist denn in zeiten gespeichert?

Mr_G 3. Sep 2005 15:18

Re: erstes Element aus dynamischem Array löschen
 
Zitat:

Zitat von brechi
Mr_G muss auch noch nen -1 hin sonst greift man auf ein element zu weit zu

:wall: Da will man mal einmal helfen... sry aber er hat natürlich Recht!
War ein Flüchtigkeitsfehler.

TheAn00bis 3. Sep 2005 15:34

Re: erstes Element aus dynamischem Array löschen
 
Danke!

Kommen zwar immer noch ständig die besagten Fehlermeldungen, aber das wird dann wohl woanders dran liegen.

Ich kann das Programm ja mal kurz erklären:

20Ampeln (können auch nur 2 sein, je nach belieben) sind auf dem Bildschrim, die alle zufalls geschaltet sind und die schalten endlos vor sich hin (also rot, grün, gelb).

Immer wenn eine Ampel grün ist, muss der Benutzer auf einen Knopf im der Main-Form klicken und dann wird die Reaktionszeit in eine Listbox geschrieben.

Was das Programm macht sollte geklärt sein, jetzt das Wie?:

Jede Ampel ist vollkommen selbstständig und sendet nur einen Befehl and die Main-Form, damit sich diese die Zeit merkt. Und dies tut sie, in dem sie das Array "Zeiten" um 1vergrößert und in das letzte Element den aktuellen gettickcount schreibt.

Klickt der Benutzer dann auf den Knopf, so wird immer das erste Element aus dem Arry vom aktuellen gettickcount subtrahiert. Das Ergebnis kommt in die Listbox.

Ich habe das ganze gerade mit nur einer Ampel ausprobiert, manchmal klappt alles einwandfrei, dann lasse ich die Ampel 5mal durchlaufen und klicke immer bei grün auf den Button und die Zeiten werden eingetragen, doch dann irgendwann kommt "Exception EInvalidPointer in module...". Es tritt immer vollkommen zufällig auf. Selbst bei nur einer Ampel. Ich hab keine Ahnung was das sein kann.

Hier mal die wichtigsten Proceduren:

Delphi-Quellcode:
procedure TMain.loesche;
var i,l: Integer;
begin
for i := 0 to high(zeiten) do
  zeiten [i] := zeiten[i +1];

l:=length(zeiten);
setlength(zeiten,l-1);
end;

procedure TMain.Button1Click(Sender: TObject); //Button der die Ampeln erstellt
begin
inc(i);
Ampel:= TAmpel.Create(Main,('Ampel'+inttostr(i)),i);
TAmpel(FindComponent('Ampel'+inttostr(i))).ein;
end;

procedure TMain.istGruen; //wird von den Ampeln aufgerufen, sobald sie grün sind
var s:integer;
begin
s:=length(zeiten);
setlength(zeiten,s+1);
zeiten[s+1]:=gettickcount;
gruen:=true;
end;

procedure TMain.Button2Click(Sender: TObject); {muss vom User geklickt werden, wenn eine Ampel auf grün schaltet}
var zeit:integer;
begin
if gruen then begin
zeit:=(gettickcount-zeiten[1]);
Listbox1.items.Add(inttostr(zeit)+'ms');
loesche;
gruen:=false;
end;
Wäre toll, wenn sich das jemand anschauen könnte.

SirThornberry 3. Sep 2005 15:51

Re: erstes Element aus dynamischem Array löschen
 
entweder
Delphi-Quellcode:
for i := 0 to length(zeiten) - 2 do
oder
Delphi-Quellcode:
for i := 0 to High(zeiten) - 1 do
einfach ein bischen mitdenken!! Denn wenn du auf zeiten[i + 1] zugreifst darf i natürlich High nie überschreiten und auch nicht (length(zeiten) - 1)

Wenn man jetzt davon ausgeht das auch bei einem dynamichen Array alle werte im Speicher hintereinander stehen kann man natürlich auch den gesammten speicherblock mit move verschieben.
Beispiel würde ich gern posten aber ich find nirgends von welchem Typ das dynamische Array ist (oder ich übersehe es einfach)

marabu 3. Sep 2005 15:56

Re: erstes Element aus dynamischem Array löschen
 
Hi,

ein paar kleine Änderungen - ohne dass ich dein Projekt ganz verstanden habe:

Delphi-Quellcode:
procedure TMain.loesche;
var
  i: Integer;
begin
  for i := 1 to high(zeiten) do
    zeiten [i - 1] := zeiten[i];
  setlength(zeiten, high(zeiten));
end;

procedure TMain.Button1Click(Sender: TObject);
//Button der die Ampeln erstellt
begin
  inc(i); // i als globale Variable ist nicht sehr glücklich
  Ampel:= TAmpel.Create(Main,('Ampel' + IntToStr(i)), i);
  TAmpel(FindComponent('Ampel'+inttostr(i))).ein;
end;

procedure TMain.istGruen;
//wird von den Ampeln aufgerufen, sobald sie grün sind
begin
  setlength(zeiten, Length(zeiten) + 1);
  zeiten[High(zeiten)] := gettickcount;
  gruen := true;
end;

procedure TMain.Button2Click(Sender: TObject);
{muss vom User geklickt werden, wenn eine Ampel auf grün schaltet}
var
  zeit: integer;
begin
  if gruen then begin
    zeit := (gettickcount - zeiten[0]);
    Listbox1.items.Add(inttostr(zeit) + ' ms');
    loesche;
    gruen := false;
  end;
end;
Grüße vom marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:51 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz