Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi static array in einem dynamic array freigeben? (https://www.delphipraxis.net/70669-static-array-einem-dynamic-array-freigeben.html)

supermuckl 2. Jun 2006 14:02


static array in einem dynamic array freigeben?
 
Hi@All

Ich code gerade viel mit records und arrays rum
Ich baue eine serveranwendung, die performant sein sollte.

Jetzt bin ich dort angelangt, wo ich Array Items löschen muss.

Dies ist eine meiner Arraykombinationen:
Delphi-Quellcode:
type Tstatusinfo = array of array[0..8] of string;
type Tstatusinfoarr = array of Tstatusinfo;

var
statusinfos: Tstatusinfoarr;
Frage:

Wenn ich jetzt aus statusinfos ein item löschen will, benutze ich diese Funktion:

Delphi-Quellcode:
procedure DeleteStatusinfosItem(index:integer);
var
i,i2,c:integer;
temp: TStatusinfoarr;
begin
if index > length(Statusinfos) then exit;
c := 0;
    setlength(temp,length(Statusinfos)-1);
    for i := 0 to length(Statusinfos)-1 do begin
        if i <> index then begin
          temp[i] := Statusinfos[i];
        inc(c);
        end;
    end;
    setlength(Statusinfos,length(temp));
    for i := 0 to length(temp)-1 do begin
        Statusinfos[i] := temp[i];
    end;
end;
Muss ich jetzt das statische array auch noch irgendwie freigeben ? oder merkt der speichermanager selbst, das auf dieses array nichts mehr zeigt und das das dann automatisch freigegeben wird?

Frage2:

wenn ich statt dem statischen arrays ein packed reckord habe mit integern und strings mit längenangabe
ist das dann mit dem statischen array freigeben gleichzusetzen?

Frage3:
was ist wenn ich ein array of array of array[x..y] habe
und ein item im primären ersten array lösche
dann müsste ich ja setlength(unterarray,0) machen, damit das 2. array auf länge 0 gesetzt wird und somit auch vom speichermanager aufgeräumt wird?
und das statische wird auch automatisch aufgeräumt?

Bitte alle 3 Fragen wenn möglich beantworten, da ich auf keinen fall ein Speicherleck haben will nacher :)

himitsu 2. Jun 2006 14:26

Re: static array in einem dynamic array freigeben?
 
Also das Static Array und Records werden im Grunde genause behandelt, wie ein einfacher Integer ... sie liegen direkt im Speicherbereich des dynamischen Arrays.

Außerdem ist
Delphi-Quellcode:
T = Array[0..4] of Integer
vom Speicheraufbau genau das selbe, wie
Delphi-Quellcode:
T = Record
  i1: Integer;
  i2: Integer;
  i3: Integer;
  i4: Integer;
  i5: Integer;
End;
und natürlich
Delphi-Quellcode:
T = Record
  i1, i2, i3, i4, i5: Integer;
End;
sogar das wäre das Selbe
Delphi-Quellcode:
T = Record
  i1, i2: Integer;
  Case Integer of
    0: (i3, i4, i5: Integer);
End;
oder das
Delphi-Quellcode:
T1 = Record
  i1, i2: Integer;
End;
T2 = Record
  i3, i4, i5: Integer;
End;
T = Record
  R1: T1;
  R2: T2;
End;
Und was weiß ich noch alles :stupid:

Es sind alles halt immer 5 Integer hintereinander.


So, nun nochmal zur Frage.
Die Static Arrays und Records werden allso immer freigegeben (egal wie man den Eintrag entfernt ... man muß nur bei anderen Metoden aufpassen was darin ist ... Strings sind ja wieder Pointer, da ist das manchmal etwas schwieriger)

Da du aber jeden Eintrag einzeln und über "normale" Zuweisungen verschiebst/kopierst, greift dir die CompilerMagig kräftig unter die arme und du brauchst dich um das Freigeben der dynamischen Arrays und Strings keine Sorgen zu machen, denn diese werden automatisch gelöscht (da fügt der Compiler die nötigen Befehle mit ein)


Schwieriger würde es allerdings, wenn du die zu verschiebenden Einträge alle auf einmal verschiebst (per CopyMem oder Co.), denn dann weiß der Compiler ja nicht, daß da eventuell was freigegeben werden müßte und man muß sich da wirklich selber drum kümmern ... der Vorteil wäre allerdings, das es wesendlich schneller wäre.
Wobei dein jetziger Weg (wenn er nicht all zu langsam ist) natürlich für einen "Anfänger", der vom internen Aufbau der Typen nicht viel Ahnung hat, vorteilhafter und weniger Fehleranfällig ist ... denn wenn du die automatischen Dinge umgehst, dann entsteht schnell mal ein MemoryLeak.

supermuckl 2. Jun 2006 14:51

Re: static array in einem dynamic array freigeben?
 
d.h. ich muss (frage3) eigentlich garnicht das verschachtelte array auf länge 0 setzen, wenn es von einem übergeordneten array nicht mehr referenziert wird?

das wäre ja dann logisch, wenn nach deiner beschreibung alles was da so baumartig verschachtelt ist( solang es keine klassen sind, die mit create erzeugt wurden usw) automatisch gefreet wird, wenn ein übergeordneter pointer nicht mehr drauf pointert :)

die "lowlevel" funktionen will ich garnicht anrühren - wenn dann würde ich ne tlist oder tobjectlist nehmen
da ich aber eh nur records usw speichern will (und keine klassen) brauch solche intelligenten listen eigenlich nicht.

noch eine kleine frage
wie sieht es mit record <> packed reckord aus?
was ist da der unterschied beim speichern in dateien über typisierte files ?

sniper_w 2. Jun 2006 15:47

Re: static array in einem dynamic array freigeben?
 
Zitat:

noch eine kleine frage
wie sieht es mit record <> packed reckord aus?
was ist da der unterschied beim speichern in dateien über typisierte files ?
Es sind sowieso zu viel Fragen für einen Thread, aber den Unterschied ist, dass die Daten in Records (unpacked) auf 4 bytes (32 Bit eben) "aligned" sind und in packed record sind es nicht.
Beispiel:
Delphi-Quellcode:
type
  rec = record
  e: byte;
  d:Byte;
end;

prec = packed record
  e: byte;
  d:Byte;
end;
// SizeOf(rec) = 4
// SizeOf(prec) = 2
Anmerkung: C structs sind immer packed records, sollte jemand was übersetzen müssen.

himitsu 2. Jun 2006 16:26

Re: static array in einem dynamic array freigeben?
 
Zitat:

Zitat von sniper_w
... aber den Unterschied ist, dass die Daten in Records (unpacked) auf 4 bytes (32 Bit eben) "aligned" sind und in packed record sind es nicht.

Deine Rec's sollten beide 2 Byte sein (da die Typen vorrangig an ihrr eigenen Göße ausgerichtet werden und wenn das nicht geht dann nach der Vorgabe ... ich hoff ich irre mich nicht gerade :? ), aber
Delphi-Quellcode:
type
rec = record
  B: Byte;
  I: Integer;
end;
// SizeOf(rec) = 8
Code:
01234567
B  IIII
und
Delphi-Quellcode:
type
rec = record
  B: Byte;
  b: Byte;
  I: Integer;
end;
// SizeOf(rec) = 8
Code:
01234567
Bb IIII

{$A4} ist ja als standard eingestellt, also 4 Byte ... man könnte aber auch z.B. {$A8} nehmen, dann sind es 64 Bit,
oder bei {$A1} / {$A-} ist es auch immer ein packed Record


[add]
PS:
selbst wenn er dabei an 4 Byte ausrichten würde, dann wären es 5 Byte :zwinker:
Code:
rec = record
  e: byte;
  d:Byte;
end;

01234
B  [color=silver]B
    ^ an der nächsten 4-Byte-Grenze ausgerichtet
      ist selbs 1 Byte groß, also 4+1=5[/color]


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:14 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