AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dynamische Arrays in Records

Ein Thema von Cyf · begonnen am 24. Jun 2008 · letzter Beitrag vom 24. Jun 2008
Antwort Antwort
Cyf

Registriert seit: 30. Mai 2008
407 Beiträge
 
Lazarus
 
#1

Dynamische Arrays in Records

  Alt 24. Jun 2008, 16:58
Ok, ich bin grade etwas verwirrt, weil ich nicht genua weiß wie Delphi damit umgehen würde, aber ihr wisst das sicher.

Gegeben ist folgender Record-Type:

Delphi-Quellcode:
TChatMsg = record
    Code: Byte; //Statuscode
    Lenght: Cardinal; //Contentlänge
    Content: array of Byte;
  end;
Das ganze Ding soll vie Netzwerk rausgeschickt werden und logischerweise auch wieder eingelesen.
Dazu muss auf der Gegenseite natürlich auch so ein Ding erstellt werden, auch kein Problem, die Frage ist, wenn ich das Array gefüllt habe und den Record-Type frei gebe (dispose), was passiert dann?
Weiß Delphi, das das Array mit freigegeben werden muss, oder muss ich seine Länge zunächst auf 0 reduzieren (oder mit anderen Worten repräsentiert das Array für Delphi nur nen Pointer). Oder wäre es vielleicht sinvoller die Sache anders anzugehen und das ganze eher so zu definieren (und entsprechen Speicher manuell zu reservieren):

Delphi-Quellcode:
TChatMsg = record
    Code: Byte; //Statuscode
    Lenght: Cardinal; //Contentlänge
    Content: Pointer;
  end;
Wahrscheinlich ne dumme Frage, aber ich dachte, bevor ichs schreib ist villeicht günstiger, erst drüber nachzudenken, wie ich die Speicherverwaltung hinterher am günstigsten bewältige.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Dynamische Arrays in Records

  Alt 24. Jun 2008, 17:03
Delphi weiß, dass da ein dynamisches Array (oder ein String) drin ist und gibt ihn frei. Da ist ein wenig Compiler-Magic im Spiel. Er unterscheidet zwischen "dynamischen" Records (also Records mit min. eine dynamischen Variable) und statischen Records.
Es gibt dazu zwei verschiedene dispose-Funktionen. Die dynamische Variante rentt dann rekursiv durch dein Record durch (mit Hilfe der RTTI).


Aber wie versendest du einen Record mit dynamischen Inhalt übers Netz?
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Cyf

Registriert seit: 30. Mai 2008
407 Beiträge
 
Lazarus
 
#3

Re: Dynamische Arrays in Records

  Alt 24. Jun 2008, 17:16
Binär, hatte ich mir das gedacht, am absender kenne ich ja die Größe und der Empfänger kann die Lenght ja auslesen und dann entsprechend viel mehr lesen. Das müsste ich bei der Pointervariante allerdings auch machen.
Bleibt nun die Frage was günstiger ist, kannst du das nochmal genauer erklären?

Also würde ein dispose(MyChatMsg); bei gefüllten Inhalt (sei es nun ein String ode binäre Daten, ist beides vorgesehen) funtionieren, ohne ein Memory-Leak zu hinterlassen?
Wie sieht das mit der Performance aus, rekursiv bedeutet da ja meistens nichts so gutes, mit dem Pointer müsste ich aber auch manuell im Prinzip nichts anderes als erst:

Delphi-Quellcode:
dispose MyChatMsg.Content //Content: Pointer
dispose MyChatMsg;
[Edit] Die Sache hat sich denke ich erledigt, weil mir grade der Vorteil erst auffällt, dass ich wenn ich das Array nehm, ich ja den ganzen Record im Speicher behalten muss, weil ich ihn nicht freigeben kann, ohne das Array dabei zu verlieren (wenn ich alles richtig versteh) oder es erst zu kopieren, aber das ist nicht der Sinn der Sache. Wenn ich den Pointer nehm, kann ich den Inhalt unabhängig vom Rest der Nachricht behalten. Die prinzipielle Fragestellung, was besser funktioniert, würde mich aber trotzdem noch intressieren.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Dynamische Arrays in Records

  Alt 24. Jun 2008, 17:45
Genauer erklären?
Die RTTI eines Records kann so beschrieben werden:
Delphi-Quellcode:
//RTTI eines Records
type PPropContent=^TPropContent;
     TPropContent=record //je ein dynamisches Element des Records
       RecordData:ppointer; //RTTI einer dynamischen Variablen innerhalb des Records
       Position:cardinal; //Position der Variablen im Record
     end;

type PRecordData=^TRecordData; //Zeiger auf RTTI
     TRecordData=record
       size:cardinal; //Größe des Records insgesamt
       PropCount:cardinal; //Anzahl der dynamischen Komponenten
       Content:array[0..16737] of TPropContent; //max(content) liegt natürlich bei PropCount
end;

Im statischen Fall würde bei einem statischen Record dein dispose vom Compiler durch freemem ersetzt (die Größe kennt der Compiler ja)
In deinem speziellen Fall wird dispose aufgerufen und noch als zweiter Parameter ein Zeiger auf die RTTI deines Records übergeben (typeInfo(TmyRecord): PRecordData).
In dieser RTTI steht die Größe deines Records drinn (für Freemem) und noch die Anzahl dynamischer Elemente (bei dir ein Array)
Und dann kommt eine List (TPropContent) mit der Postion der Variable im Array und einen Zeiger auf die RTTI dieser Variablen. Und genau dort schaut er jetzt und sieht, dass es ein Array ist und ruft dann finalizeArray auf.
Über Zeitprobleme würde ich dabei nicht reden und die bequeme Variante über das Array wählen. (Ansonsten könntest du ja gleich in C programmieren )
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Cyf

Registriert seit: 30. Mai 2008
407 Beiträge
 
Lazarus
 
#5

Re: Dynamische Arrays in Records

  Alt 24. Jun 2008, 18:01
Vielen Dank für deine Mühe , das ist intressantes Hintergrundwissen dazu (ich hasse es immer, wenn die Compiler-magic was macht und ich kann nicht sagen was). Ich entscheide mich aus obigen Grund trotzdem mal für den Pointer, nicht daas die paar Bytes die ich behalten müsste groß was ausmachen, aber ich kann noch nicht abschätzen, ob ich dasirgendwann mal für was benutze, wo ich die Daten länger brauch und will die Unit nicht jedesmal umschreiben müssen.

Zitat:
Über Zeitprobleme würde ich dabei nicht reden und die bequeme Variante über das Array wählen. (Ansonsten könntest du ja gleich in C programmieren Mr. Green )
Hab ich ursprünglich mal, aber meine Schule zwingt mich leider im Moment dazu stupide mit Delphi-Linien auf Canvas-Objekte zu zeichnen und ich will nicht ständig in der Sprache umdenken (und außerdem ists extrem nervig in C was anderes als Konsolenanwendungen zu schreiben, weil man sich ständig mit System-Aufrufen rumquält).

[Edit]Code-Tag erwischt gehabt
  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 11:22 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