Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Auf dynamischen Speicher zugreifen
reimo - Fr 27.02.04 13:00
Titel: Auf dynamischen Speicher zugreifen
also, folgendes Problem:
ich empfange über IP ein telegram mit dynamischer Länge, also reserviere ich den dafür nötigen Speicher auch dynamisch:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| Cnt : Integer; pBuffer : ^Byte; bRec: Byte;
Cnt := Socket.ReceiveLength; GetMem( pBuffer, Cnt );
Socket.ReceiveBuf( pBuffer^, Cnt );
for i := 0 to Cnt-1 do begin bRec := pBuffer[i]; end;
bRec: ^Byte;
bRec := pBuffer; for i := 0 to Cnt-1 do begin ... Inc(bRec); end; |
wie kann ich auf die einzelnen Bytes des reservierten Speichers zugreifen??
wieso kann ich einen Pointer nicht inkrementieren?
mfg
reimo
Moderiert von
Tino: Titel geändert.
ErnestoChe - Fr 27.02.04 13:27
Hallo,
ich nehme mal an, dass du versuchst es wie in C zu machen. Was Pointer und Arrays angeht unterscheidet sich Delphi von C. In deinem Fall würde ich einfach einen Pointer auf ein Byte-Arry machen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| type TByteArr = array of Byte; PByteArr = ^TByteArr;
var pBuffer: PByteArr;
pBuffer := New(PByteArr); SetLength(pBuffer^, Cnt); |
MFG
- Ernesto -
Phantom1 - Fr 27.02.04 13:30
oder wenn du kein PByteArray verwenden möchtest, so hier:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Cnt: Integer; pBuffer, bRec: PByte;
Cnt := Socket.ReceiveLength; GetMem(pBuffer, Cnt);
Socket.ReceiveBuf(pBuffer^, Cnt);
bRec := pBuffer; for i := 0 to Cnt-1 do begin ... Inc(bRec); end; |
reimo - Fr 27.02.04 13:41
cool, danke für die Antworten
wusste garnicht, dass man die Länge eines arrays dynamisch ändern kann.
in diesem Fall kann ich gleich die Funktion SetLength verwenden und mir den Zugriff über Pointer ersparen (falls ichs richtig verstanden habe)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| Buffer : array of Byte;
Cnt := Socket....
SetLenght( Buffer, Cnt); Socket.Receive( Buffer, Cnt );
for i := 0 to Cnt do begin xx := Buffer[i] end; |
@Phantom1
was wäre bei deinem Vorschlag der Unterschied zu meinem 2ten Versuch?
du hast bRec als PByte deklariert, ich dagegen als ^Byte, ist das nicht das selbe?
mfg
reimo
Motzi - Fr 27.02.04 13:41
| ErnestoChe hat folgendes geschrieben: |
Hallo,
ich nehme mal an, dass du versuchst es wie in C zu machen. Was Pointer und Arrays angeht unterscheidet sich Delphi von C. In deinem Fall würde ich einfach einen Pointer auf ein Byte-Arry machen:
Delphi-Quelltext 1: 2: 3:
| type TByteArr = array of Byte; PByteArr = ^TByteArr; | |
Aber was du hier deklarierst ist ein Zeiger auf ein
dynamisches Array und das kann ganz schnell Probleme machen..!
In der Unit SysUtils ist bereits ein Type TByteArray bzw PByteArray deklariert:
Delphi-Quelltext
1: 2:
| PByteArray = ^TByteArray; TByteArray = array[0..32767] of Byte; |
Und mit so einer Deklaration funktioniert dann auch der gewünschte Zugriff...
ErnestoChe - Fr 27.02.04 14:40
Hallo,
| Zitat: |
| Aber was du hier deklarierst ist ein Zeiger auf ein dynamisches Array und das kann ganz schnell Probleme machen..! |
Hast du eine weitere Begründung, außer kann ganz schnell Probleme machen?
Es war nur ein Beispiel, um einen Denkanstoß zu geben. Er muss selber wissen ob das Array dynamisch oder statisch sein muss. Wenn man mit dem dynamischen Array sauber umgeht, kann auch nichts passieren.
MFG
- Ernesto -
Motzi - Fr 27.02.04 16:29
Ein dynamischer Array ist in Delphi (genauso wie auch Strings) nur ein Pointer der implizit dereferenziert wird. Mit einem Pointer auf einen dyn. Array hast du also praktisch einen Pointer auf einen Pointer und daher in diesem Fall unbrauchbar...
ErnestoChe - Fr 27.02.04 17:49
Hallo,
| Zitat: |
| Mit einem Pointer auf einen dyn. Array hast du also praktisch einen Pointer auf einen Pointer und daher in diesem Fall unbrauchbar |
Stimmt, dynamische Arrays sind implizit Zeiger. Daher ist es zwar nicht unbrauchbar aber wohl unnötig.
Apropos Zeiger auf Zeiger. Wieso machst du eigentlich in deinem
Pointer-Tutorial [
http://www.delphi-forum.de/viewtopic.php?t=10926] sowas:
| Zitat: |
| type PMultipleForm = ^TMultipleForm; |
MFG
- Ernesto -
Motzi - Fr 27.02.04 18:16
| ErnestoChe hat folgendes geschrieben: |
| Stimmt, dynamische Arrays sind implizit Zeiger. Daher ist es zwar nicht unbrauchbar aber wohl unnötig. |
In diesem Fall ist es schon unbrauchbar..! Probier mal diesen Code aus, dann siehst du auch warum:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| const MAX_COUNT = 255;
type PDynByteArray = ^TDynByteArray; TDynByteArray = array of Byte;
PStatByteArray = ^TStatByteArray; TStatByteArray = array [1..MAX_COUNT] of Byte;
procedure TForm1.Button1Click(Sender: TObject); var szArray: array [1..MAX_COUNT] of Byte; pDynArray: PDynByteArray; pStatArray: PStatByteArray; i: Integer; begin Listbox1.Clear; Listbox2.Clear;
for i := 1 to MAX_COUNT do szArray[i] := i;
pDynArray := @szArray[1]; pStatArray := @szArray[1]; for i := 1 to MAX_COUNT do Listbox1.Items.Add(IntToStr(pStatArray^[i]));
for i := 1 to MAX_COUNT do Listbox2.Items.Add(IntToStr(pDynArray^[i])); end; |
Bei der zweiten Schleife (in der eigentlich die Werte in die Listbox2 eingetragen werden sollten) wirst du nämlich mit einer wunderschönen EAccessViolation Exception begüßt.... Warum? Weil ein Zeiger auf einen dyn. Array eben ein Zeiger auf einen Zeiger ist welcher implizit nochmal dereferenziert wird. Dh die ersten 4 Bytes des Arrays auf das der Zeiger zeigt werden nochmal dereferenziert womit du an der Adresse $01020304 landest an der dann versucht wird auf den eigentlichen Array zuzugreifen...
Weil ich hier den Einsatz von Pointern und dyn. Speicherallozierung zeigen wollte.. du hast recht es sind im Prinzip auch wieder Zeiger auf Zeiger, aber wenn ich mich recht erinnere hab ich ganz am Schluss auch extra geschrieben, dass man das ganze auch ohne extra Zeiger machen kann da Objekte ohnehin nur Zeiger sind... Ich weiß das Beispiel ist nicht unbedingt gut gewählt, aber es ist schon sehr lang her dass ich das Tutorial damals geschrieben hab und ich in der zwischenzeit auch viel neues dazu gelernt, aber ich war bis jetzt zu faul das Tutorial zu überarbeiten... ;)
ErnestoChe - Sa 28.02.04 23:25
Hallo,
@Motzi
Du hast Recht. Naja, meine Muttersprache ist nun mal C/C++.
| Motzi hat folgendes geschrieben: |
| Ich weiß das Beispiel ist nicht unbedingt gut gewählt, aber es ist schon sehr lang her dass ich das Tutorial damals geschrieben hab und ich in der zwischenzeit auch viel neues dazu gelernt, aber ich war bis jetzt zu faul das Tutorial zu überarbeiten...:wink: |
OK, kann man verstehen :wink:
MFG
- Ernesto -
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!