Autor |
Beitrag |
reimo
      
Beiträge: 75
|
Verfasst: Fr 27.02.04 13:00
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
      
Beiträge: 528
Win 2000 pro, CRUX 2.0
Delphi 6 Pers, Open K3
|
Verfasst: 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
      
Beiträge: 390
|
Verfasst: 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 
      
Beiträge: 75
|
Verfasst: 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
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: 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...
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
ErnestoChe
      
Beiträge: 528
Win 2000 pro, CRUX 2.0
Delphi 6 Pers, Open K3
|
Verfasst: 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
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: 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...
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
ErnestoChe
      
Beiträge: 528
Win 2000 pro, CRUX 2.0
Delphi 6 Pers, Open K3
|
Verfasst: 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 sowas:
Zitat: | type PMultipleForm = ^TMultipleForm; |
MFG
- Ernesto -
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: 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:
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...
Zitat: | Apropos Zeiger auf Zeiger. Wieso machst du eigentlich in deinem Pointer-Tutorial sowas:
Zitat: | type PMultipleForm = ^TMultipleForm; |
|
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... 
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
ErnestoChe
      
Beiträge: 528
Win 2000 pro, CRUX 2.0
Delphi 6 Pers, Open K3
|
Verfasst: 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... |
OK, kann man verstehen
MFG
- Ernesto -
|
|