AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Delphi Schlüsselwort absolute
Tutorial durchsuchen
Ansicht
Themen-Optionen

Schlüsselwort absolute

Ein Tutorial von Dezipaitor · begonnen am 21. Aug 2007 · letzter Beitrag vom 21. Aug 2007
Antwort Antwort
Seite 2 von 2     12   
Dezipaitor
Registriert seit: 14. Apr 2003
hi

kennt jemand noch das Delphischlüsselwort "absolute" ?
Mit dem kann man eine Speicherstelle durch eine weitere Variable beschreiben.

Delphi-Quellcode:
var i : Integer;
    i2 : Cardinal absolute i;
begin

Beide Variablen zeigen auf denselben Speicherbereich. Der Wert ist zwar der gleiche, jedoch nur dann, wenn i2 < high(i) is. Sonst wird i < 0.

Man kann dieses Spielchen auf für normale Parameter machen :
Delphi-Quellcode:
procedure XY(i : Integer);
var i2 : Cardinal absolute i;
begin
und für Rückgabewerte:

Delphi-Quellcode:
function XY : Integer;
var i2 : Cardinal absolute result;
begin
Wirklich nützlich ist das Schlüsselwort jedoch, wenn man einen Array hat, der aus der C Sparte stammt :

Delphi-Quellcode:
type PData = ^TData;
       TData = record
         Member : ...
         ...
       end;


procedure XY(pArray : PData);
var
   anArray : Array of pArray absolute pArray;
begin
In einem Array pArray, befinden sich die Elemente gerade soweit auseinander, wie die Größe von TData ist (ungepackter Zustand). D.h. wenn man durch die Elemente gehen will,
dann muss man normalerweise entweder :
1. Eine explizite Typkonvertierung machen
2. Einen Zeiger soweit verschieben, dass er aufs nächste Element zeigt.

Das ist jedoch nicht nötig.
Delphi-Quellcode:
procedure XY(pArray : PData);
var
   anArray : Array of pArray absolute pArray;
   i : Integer;
begin
  for i := 0 to 5 do
    anArray[i].Member := ...;
Was jedoch notwendig ist, dass mann die Grenzen kennt. Die obere und die Untere. Man sollte nicht auf high(anArray), low(anArray) und length(anArray) vertrauen,
da der dynamische Array nicht korrekt erstellt wurde.
Zudem sollte man auf SetLength verzichten, da es sich ja garnicht um einen echten dynamischen delphi Array handelt.


Delphi-Quellcode:
procedure XY(pArray : PData; iCnt : Integer;);
var
   anArray : Array of pArray absolute pArray;
   i : Integer;
begin
  for i := 0 to iCnt do
    anArray[i].Member := ...;

Zudem sollte man sowas immer kommentieren und nicht als Allheilmittel einsetzen.


Viel Spass
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
 
Dezipaitor

 
Delphi 7 Professional
 
#11
  Alt 21. Aug 2007, 21:59
Zitat von xaromz:
Hallo,
das ist eine ganz normale Lösung, die wunderbar funktioniert. Gefährlich ist die nicht, der Aufrufer darf nur nicht vergessen, den Speicher wieder freizugeben. Deshalb sollte für einen solchen Zweck eine Prozedur genommen werden, der man den Speicherbereich übergibt; dann muss der Aufrufer sowohl den Speicher anfordern als auch wieder freigeben. Deine erste Variante hingegen ist sehr gefährlich, da sie einen Pointer auf eine lokale Variable zurückgibt, der nach dem Aufruf nicht mehr gültig ist.

Gruß
xaromz
Das mit dem Speicher freigeben, mag zwar stimmen, jedoch ist Vergessen immer möglich. Und eigentlich hat es hiermit garnichts zu tun.

Dass der Aufrufer den Speicher reservieren muss ist jedoch viel gefährlicher, weil man nie sagen kann, ob der Speicher überhaupt genug ist. Nebenbei ist dem Aufrufer garnicht bekannt wie groß der Array sein wird. Er ist dynamisch. Aber das ist unter den Tisch gefallen, der Einfachheit wegen.
Dass der Benutzer ihn freigibt ist auch kein Problem. Man schreibt es direkt in den Funktionskommentar. Dazu könnte man noch eine Funktion schreiben, die ihn freigibt. Schon die Anwesenheit davon, fordert zum Aufruf auf. Man könnte die Objekte auch intern noch verwalten und am Ende freigen (ala VCL und Owner) - aber das kann auch ihn die Hose gehen.



Zitat von Muetze1:
Mein Vorschlag:

Delphi-Quellcode:
function GetAccessNames(out iCount : Cardinal): PSI_ACCESS;
var lSiEntry: PSI_ACCESS;
    i : Cardinal;
begin
  iCount := 32;
  GetMem(lSiEntry, Sizeof(si) * iCount);
  result := lSiEntry;

  for i := 0 to iCount -1 do
  begin
    hier zugriff auf lSiEntry^ ganz leicht

    Inc(lSiEntry);
  end;
end;
Der Vorschlag ist nur zum Elementzugriff. Die angesprochene Alloziierung von Speicher welche auf einer anderen Ebene freigegeben wird, ist hier nicht korrigiert und sollte wie von xaromz beschrieben gelöst werden.
Das ist zwar auch eine Möglichkeit, jedoch ist diese meiner Meinung nach schlecht, da es von C her stammt und Delphi nicht würdig ist. Man kann auch nicht auf beliebige Arrayelemente durcheinander zugreifen.
Christian
  Mit Zitat antworten Zitat
Muetze1
 
#12
  Alt 21. Aug 2007, 22:20
Zitat von Dezipaitor:
Das ist zwar auch eine Möglichkeit, jedoch ist diese meiner Meinung nach schlecht, da es von C her stammt und Delphi nicht würdig ist.
Wie bitte? Was ist das denn für eine Begründung? Nur weil es ein Zeiger ist darf man ihn in Delphi nicht nutzen oder was für Klischees werden hier bedient? Man muss die Möglichkeiten der Sprache der Situation entsprechend (aus)nutzen. Die Lösung ist eine gute Lösung zwischen Aufwand, Anweisungszahl und Optimierung. Grundlegend kann ich dem sogar nicht schlechtes abgewinnen. Lieber diese Lösung als ein Zeiger auf statisches Array mit einem Element und extra abgeschalteter Bereichsprüfung (das ist Delphi nicht würdig, schliesslich bietet Delphi eine Typsicherheit und eine gute Bereichsprüfung) oder ein Zeiger auf statischer Array was einen gleichzeitig in der Anzahl der Elemente begrenzt.

Zitat von Dezipaitor:
Man kann auch nicht auf beliebige Arrayelemente durcheinander zugreifen.
Du hast eine Schleife vorgegeben. Wenn es Random Access zu den Elementen gewahrt bleiben muss gibt es gewiss andere Lösungen (ein guter Teil wurde hier schon aufgezeigt). Grundlegend diente es nur als weiteres Lösungsbeispiel.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 07:48 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