AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Library: Object-Pascal / Delphi-Language Delphi [Win32] Eintrag aus dynamischen Array löschen
Thema durchsuchen
Ansicht
Themen-Optionen

[Win32] Eintrag aus dynamischen Array löschen

Ein Thema von jim_raynor · begonnen am 7. Dez 2004
Antwort Antwort
Benutzerbild von jim_raynor
jim_raynor

Registriert seit: 17. Okt 2004
Ort: Berlin
1.251 Beiträge
 
Delphi 5 Standard
 
#1

[Win32] Eintrag aus dynamischen Array löschen

  Alt 7. Dez 2004, 20:08
Sicher kennen viele dass Problem, einen Eintrag aus einem dynamischen Array zu löschen. Delphi stellt keine vorgefertigte Funktion zur Verfügung, so dass man jedes mal eine eigene Löschroutine schreiben muss. Auch mich hat die Sache genervt und ich habe mich rangesetzt und eine Funktion geschrieben, die genau dies kann.

Delphi-Quellcode:
procedure DeleteArray(const ArrayPtr: Pointer; TypInfo: PTypeInfo; Index: Integer);
var
  NewElem: Integer;
  ElemSize: Integer;
  ElemAddr: Integer;
  ElemCount: Integer;
begin
  Assert(TypInfo.Kind=tkDynArray,'Es werden nur Dynamische Arrays unterstützt');
  // Elementgröße ermitteln
  ElemSize:=PInteger(PByte(Integer(TypInfo)+1)^+Integer(TypInfo)+2)^;
  // Elementanzahl ermitteln
  ElemCount:=PInteger(Integer(ArrayPtr^)-4)^;

  ElemAddr:=Integer(ArrayPtr^)+(Index*ElemSize);

  // Eintrag freigeben

  // Prüfen ob ein Finalize notwendig ist, dazu muss in der Type
  asm
    pushad
    mov esi,TypInfo
    xor eax,eax
    mov al,[esi+$01]
    add esi,eax
    add esi,$06

    mov eax,[esi]
    test eax,eax
    jz @end

    mov edx,[eax]
    mov eax,ElemAddr
    call system.@finalize

  @end:
    popad
  end;
  MoveMemory(Pointer(ElemAddr),Pointer(ElemAddr+ElemSize),ElemSize*((ElemCount-1)-index));
  NewElem:=ElemCount-1;
  // Letztes Element mit nullen füllen
  ZeroMemory(Pointer(Integer(ArrayPtr^)+(NewElem*ElemSize)),ElemSize);

  // Array verkleinern
  asm
    mov ebx,NewElem
    push ebx
    mov ecx,$00000001

    mov edx,TypInfo

    mov eax,ArrayPtr
    call system.@DynArraySetLength
    add esp,$04
  end;
end;
Ich will nicht behaupten, dass diese Funktion in allen Delphi-Versionen funktioniert, da direkt auf Typinformationen und Compilerinterne Funktionen zugegriffen wird, die sich von Version zu Version ändern können. Jedenfalls wurde die Funktion für D5, D6 und D7 erfolgreich getestet. Leider musste ich ein paar schmutzige Asm-Tricks einbauen (die ich nicht mehr erklären kann) da der Compiler mit einigen Registern gemacht hat, was er wollte. Und leider weiss ich auch nicht mehr, was alles im einzelnen bedeutet. Die Funktion habe ich schon vor längerer Zeit erstellt.

Vieles hab ich rausgefunden, in dem ich einfach SetLength irgendwo gemacht habe und mir den asm Output dazu angeschaut habe. Wie man sieht benutze ich auch Finalize um zum Beispiel bei Records enthaltene Strings freizugeben. Objekte müssen aber natürlich wie gewohnt selber freigegeben werden.

Nun gut jetzt noch ein paar Worte zur Benutzung. Wichtig ist dass das Array als eigener Typ definiert wird.
Delphi-Quellcode:
type
  TArrayType = Array of String;
Der Aufruf erfolgt dann relativ einfach:

Delphi-Quellcode:
var
  Arr : TArrayType;
begin
  SetLength(Arr,100);
  Arr[10]:='Test';
  DeleteArray(Addr(Arr),TypeInfo(TArrayType),10);
Parameter 1 gibt die Adresse der Array-Variablen an. Paramater 2 die Typeninformation des Arrays. Erst dadurch bekomme ich Elementgrösse und benötigte Finalisierungsprozesse raus. Paramater 3 gibt schliessen den zu löschenden Eintrag an.

So hoffe das diese Informationen hilfreich sind.
Christian Reich
Schaut euch mein X-COM Remake X-Force: Fight For Destiny ( http://www.xforce-online.de ) an.
  Mit Zitat antworten Zitat
Antwort Antwort

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:35 Uhr.
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