Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 08:54

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Negative Pointer
BeitragVerfasst: Fr Jun 25, 2004 14:43 
Offline
DGL Member

Registriert: Mo Jan 20, 2003 20:10
Beiträge: 424
Wohnort: nähe Starnberg
Hallo,

wenn ich mit Pointer arbeite und ich möchte den Pointer um 16 Bytes erhöhen, dann muss ich wie folgt vorgehen:
Code:
  1.  
  2. Neuer_Pointer := POINTER(INTEGER(Alter_Pointer) + 16);
  3.  


Ich konvertiere den Pointer in einen Integerwert. Meine Frage ist nun, ob ein Pointer mal grösser $8000000, also negative Werte, annehmen kann. Dann müsste ich den Pointer mit Cardinal konvertieren, damit ich $80000010 bekomme und nicht $7FFFFFEF, was dann eine positive Zahl wäre.

Oder liege ich komplett falsch, was meine Überlegungen angeht?

Gruß
KidPaddle

_________________
http://www.seban.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 25, 2004 14:59 
Offline
DGL Member

Registriert: Do Mai 30, 2002 18:48
Beiträge: 1617
Pointer niemals in generische oder ordinale, besonders vorzeichenbehaftete typen casten... das verträgt sich weder mit plattformunabhängigkeit, noch mit unterschiedlichen pascal compilern...
geht insgesamt viel einfacher: nimm einen typisierten pointer:
Code:
  1.  
  2. var
  3. a : array[0..15] of byte;
  4. p : ^byte;
  5.  
  6. begin
  7.   p := @a[0];
  8.   Inc(p, 15);
  9.  

so zeigt p auf a[15]. Identisch gehts mit allen typen, da Inc(p, 15) nicht byteweise, sondern in schritten der grösse des elements auf das gezeigt wird, also z.b. 1 Byte bei P : ^Char und ^Byte und 4 bytes bei ^Cardinal.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 25, 2004 15:10 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 13, 2002 12:18
Beiträge: 1063
Unabhängig davon, dass Delphic's Methode sprachkonformer ist, wäre es allerdings völlig egal, ob du nun vorzeichenbehaftete 32 Bit Werte zum casten nimmst oder nicht.
Die Addition unterscheidet nicht, ob das oberste Bit ein Vorzeichen ist - allesfalls bekommst du einen Integerüberlauf, falls Range Checking eingeschaltet ist, die erhaltene Bitmaske ist allerdings die selbe, und die wird ohnehin wieder als Pointer interpretiert.

Ein Zeiger könnte übrigens durchaus "negative" Werte annehmen (bzw. kennen Zeiger kein Vorzeichenbit), da Speicheradressen mehr oder weniger virtuell sind, und nicht direkt den tatsächlichen Ort im Ram repräsentieren, auch wenn Delphi, wie die meisten Programmiersprachen, dem Programmierer ein Flat Memory Modell zur Verfügung stellt, sodass wir uns in den meisten Fällen nicht mit Segmentselektoren und Speicherseiten herumschlagen müssen.

_________________
Viel Spaß beim Programmieren,
Mars
http://www.basegraph.com/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 25, 2004 15:20 
Offline
DGL Member

Registriert: Do Mai 30, 2002 18:48
Beiträge: 1617
das problem ist nicht, ob die addition hinhaut oder nicht... ein casten in einen int kann je nach compiler version nach der tatsächlcihen addition in der cpu eine ganze reihe an bits plätten, was sicher nicht sinn und zweck der ganzen sache ist. wenn Integer wie bei vielen Pascal versionen 16bittig ist, ist der daraus resultierende pointer wertlos. ähnlich sieht es aus, wenn Integer 32 bit ist, der Pointer aber 64 Bit groß - wieder sind 32 Bits einfach ausgemerzt - casten sollte sich jedenfalls bei ordinaltypen wie ein modulo 2^n verhalten.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 25, 2004 15:34 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 13, 2002 12:18
Beiträge: 1063
Ist völlig korrekt, allerdings könnte dann auf einem 64 Bit System ein Integer ebenfalls 64 Bit breit sein - und wenn Borland keinen native Win64 Kompiler (oder eine entsprechende Linuxvariante) rausbringt, gibt es ohnehin keine Zeiger mehr, die man inkrementieren könnte - jedenfalls würde ich mir in dieser Hinsicht keine Sorgen machen, ob ich jetzt einen Zeiger inkrementiere (schöner ist es allerdings), in einen Integer oder Cardinal caste, oder manche Operationen direkt im Inlineassembler durchführe.

Wenn ich mal so nahe am System arbeite, wird eine Portierung auf andere Systeme ohnehin aufwändiger, dann ist's grad schon egal :wink:

_________________
Viel Spaß beim Programmieren,
Mars
http://www.basegraph.com/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 25, 2004 16:07 
Offline
DGL Member

Registriert: Mo Jan 20, 2003 20:10
Beiträge: 424
Wohnort: nähe Starnberg
Danke für die Info. Leider sind die Typen auf dem die Pointer zeigen zur Compilierung nicht bekannt. Ich realisiere einen variablen Buffer, in dem ich Daten einfügen und löschen kann. Dabei wird eine ID, die Grösse und die Daten selber gespeichert, in der Form:

Code:
  1.  
  2. |ID|Size|Data|ID|Size|Data|....|ID|Size|Data
  3.  


Das Objekt selber ist so aufgebaut:
Code:
  1.  
  2.   TVarBuffer       = class(TObject)
  3.   protected
  4.     fOffset          : Cardinal;
  5.     fData            : Pointer;
  6.     fCount           : Integer;
  7.     fUsedSize        : Cardinal;
  8.     fReservedSize    : Cardinal;
  9.     function  EOB : Pointer;
  10.     function  ValidPtr(aPtr : Pointer) : Boolean;
  11.     function  vbAddPointer(aPtr : Pointer; aSize : Integer) : Pointer;
  12.     function  vbAddHeader(aPtr : Pointer; aHeader : Pointer) : Pointer;
  13.     function  vbGetPos(aID : Integer; var aData : Pointer; var aSize : Integer) : Boolean;
  14.     function  vbAppend(aID : Integer; aSize : Integer; Data : Pointer) : Boolean;
  15.     function  vbDelete(aID : Integer) : Boolean;
  16.   public
  17.     constructor Create(aOffset : Cardinal);
  18.     destructor Destroy; override;
  19.  
  20.     procedure LoadFromStream(aStream : TStream);
  21.     procedure SaveToStream(aStream : TStream);
  22.  
  23.     function  ExistsID(aID : Integer) : Boolean;
  24.     function  SizeOfID(aID : Integer) : Integer;
  25.     function  WriteID(aID : Integer; aSize : Integer; aSource : Pointer) : Boolean;
  26.     function  ReadID(aID : Integer; aSize : Integer; aDest : Pointer) : Boolean;
  27.     function  DeleteID(aID : Integer) : Boolean;
  28.  
  29.     property Count : Integer read fCount;
  30.     property Data : Pointer read fData;
  31.     property UsedSize : Cardinal read fUsedSize;
  32.   end;
  33.  


Dem Buffer ist es egal, welche Daten gelesen oder geschrieben werden. Da ich die Daten später in einem Stream schreiben oder lesen will, sollen die Daten hintereinander im Speicher abgelegt sein, um eine möglichst schnelle Bearbeitung zu ermöglich. Der Augenmerk liegt auf Geschwindigkeit.

Gruß
KidPaddle

_________________
http://www.seban.de


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 15 Queries | GZIP : On ]