Autor Beitrag
knittel
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71
Erhaltene Danke: 2

Win XP, Win7, openSUSE
Delphi 7
BeitragVerfasst: Do 14.04.11 11:22 
Hallo allerseits,
vermutlich nerven meine dummen fragen schon, aber ich komme mal wieder nicht weiter. Ich will aus einem array aus pointer ein element löschen. Die pointer zeigen auf einen Record namens TMapPoint. Jeder dieser Punkte ist mit mindestens einem anderen verbunden, und haben deswegen ein eigenes dynamisches Array vom Typ: array of byte, indem sie den index der verbunden Punkte speichern. Beim Löschen erhalte ich auf jeden Fall haufenweise Fehlermeldungen wie Access Violation oder EInvalid Pointer operation.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
      DirectLoad := 
      FindNearest(Point(
      - Form1.Left + CurrentCursorPosition.X - 178,
      - Form1.Top + CurrentCursorPosition.Y - 14)); // Der Index des nächsten Punktes wird gesucht.

      Dispose(MapInfo[DirectLoad]); // Ich gebe den Speicher dieses Punktes frei.
      // Nun sollen die Zeiger ab diesem immer dorthin zeigen, wo der nächste hinzeigt.
      for Index := DirectLoad to Length(MapInfo) - 2 do
        begin
        MapInfo[Index] := MapInfo[Index + 1];
        end;
      // Dann zeigt der sowohl der vorletzte als auch der letzte auf das selbe Objekt. Deswegen können wir den letzten pointer löschen:
      SetLength(MapInfo, Length(MapInfo)-1);
      // Hier versuche ich die Indexe zu reparieren.
      FixArrayItems(DirectLoad);
      end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure FixArrayItems(N: Byte);
var i,j: integer;
begin
for i:= 0 To Length(MapInfo)-1 do // alle Elemente durchgehen.
  begin
  j := Length(MapInfo[i]^.ConnectedTo)-1// durch das array mit den indexen der verbundenen Punkte gehen.
  while j>=0 do
    begin
    // Wird auf den Punkt gezeigt der zerstört wurde, soll das Array gekürzt werden.
    if MapInfo[i]^.ConnectedTo[j] = N then
      DeleteArrayItem(MapInfo[i]^.ConnectedTo, j)
    else
    // Ist der Index größer soll der Index um 1 verringert werden.
      if MapInfo[i]^.ConnectedTo[j] > N then
      MapInfo[i]^.ConnectedTo[j] := MapInfo[i]^.ConnectedTo[j] - 1;
    j:=j-1// Nächste Verbindung.
    end;
  end;
end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure DeleteArrayItem(var A: TXArray; const Index: integer);
var
  ALength: cardinal;
  TailElements: cardinal;
begin
  ALength := Length(A);
  Assert(ALength > 0);
  Assert(Index < ALength);
  TailElements := ALength - Index;
  if TailElements > 0 then
    Move(A[Index + 1], A[Index], SizeOf(TLabel) * TailElements);
  SetLength(A, ALength - 1);
end;


(TXArray = array of byte)

Ich habe mir im Code Breakpoints gesetzt. Doch der Fehler kommt nicht während dieser Berechnung sondern danach in der Prozedur in der die Punkte gezeichnet werden:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
procedure DrawPoints();
var i, j: integer;
begin
with Form1.AdDraw.Canvas do
  begin
  // Set Canvas
  Pen.Color := NewColor;
  Brush.Style := absolid;
for i:= 0 to Length(MapInfo)-1 do
  begin
  for j := 0 To Length(MapInfo[i]^.ConnectedTo)-1 do
    Line(MapInfo[i]^.X + 174 + 3 + random(2), MapInfo[i]^.Y + 14 - 1 + random(2),
         MapInfo[MapInfo[i]^.ConnectedTo[j]].X + 174 + 3 + random(2),
         MapInfo[MapInfo[i]^.ConnectedTo[j]].Y + 14 - 1 + random(2));
  if MapInfo[i].PlayerPoint <> 0 then
    Textout(MapInfo[i]^.X + 174 - 1, MapInfo[i].Y + 14 - 8, IntToStr(MapInfo[i].PlayerPoint))
  else
    Rectangle(MapInfo[i]^.X + 174 + 2, MapInfo[i]^.Y + 14 - 2,
              MapInfo[i]^.X + 174 + 6, MapInfo[i]^.Y + 14 + 2);
  end;

  // Reset Canvas
  Pen.Color := BlackColor;
  Brush.Style := abclear;
  end;
end;


Im Normalfall läuft diese Prozedur gut, nur nach dem Löschen eines Punktes kommt eine Fehlermeldung meistens Access Violation oder EInvalid Pointer Operation.

Vielen Dank im voraus.

_________________
"Wir können nicht fliehen!" "Wieso nicht?" "Sie haben mir die Schnürsenkel zusammengebunden!" "Die Schweine."
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Do 14.04.11 11:59 
Wenn (TXArray = array of byte) ist, warum benutzt Du dann SizeOf(TLabel) in diesem Schnipsel?
ausblenden Delphi-Quelltext
1:
2:
  if TailElements > 0 then
    Move(A[Index + 1], A[Index], SizeOf(TLabel) * TailElements);

Wenn SizeOf(TLabel) <> 1 ist, wirst Du ziemlich sicher gegen die Wand moven, da Du mehr verschieben willst als eigentlich da ist.
knittel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71
Erhaltene Danke: 2

Win XP, Win7, openSUSE
Delphi 7
BeitragVerfasst: Do 14.04.11 12:20 
Ich hatte diesen Code Schnipsel mal als Open Source im Internet gefunden und verwendet ohne weiter nachzudenken. Ich probiers mal anders. Danke.

EDIT:
ES FUNKTIONIERT!!!!!!!!!!!!! JAAAAAAAAAAAAAA... Saß gestern 3 und heute nochmal 2 stunden an diesem Problem und bin beinahe verrückt geworden.
Danke :) :) :)

_________________
"Wir können nicht fliehen!" "Wieso nicht?" "Sie haben mir die Schnürsenkel zusammengebunden!" "Die Schweine."