Autor Beitrag
Thomas_1110
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win Vista
Delpi 7 Personal
BeitragVerfasst: Di 24.06.03 20:04 
Hallo Forum

Eines was mich beschäftigt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var Puffer: Pointer;
begin
  GetMem(Puffer, 255);
  PChar(Puffer^) :='Testtext';
  Showmessage(PChar(Puffer^));
  Freemem(Puffer, 255);
end;

funktioniert.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var Puffer: Pointer;
begin
  GetMem(Puffer, 255);
  GetLogicalDriveStrings(255, PPuffer);
  Showmessage(PChar(Puffer^));
  Freemem(Puffer, 255);
end;

gibt bei mir eine Fehlermeldung. ändere ich es so
ausblenden Delphi-Quelltext
1:
Showmessage(PChar(Puffer));					

dann funktionierts.

Weiteres noch: wie kann ich aus Puffer am besten die einzelnen Strings auslesen. Verwende Delpie 3 pro.

Gruß Thomas

Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Di 24.06.03 20:25 
Zitat:
PChar(Puffer^) :='Testtext';

Weißt du, was du da machst? Anscheinend nicht, denn damit greiftst du auf einen Speicherbereich zu, dessen Adresse du durch das Konvertieren der ersten 4 Zeichen des neu reservierten Speichers in einen PChar erhältst. Das das zu einer Schutzverletzung führen sollte, ist dir doch klar. Aber anscheinend hast du Glück und somit eine Zeitbombe geschrieben.

Die richtige Konvertierung wäre PChar(Puffer) (ohne das "^"-Zeichen)

_________________
Ist Zeit wirklich Geld?
Thomas_1110 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win Vista
Delpi 7 Personal
BeitragVerfasst: Di 24.06.03 20:51 
Zitat:
Weißt du, was du da machst? Anscheinend nicht, denn damit greiftst du auf einen Speicherbereich zu, dessen Adresse du durch das Konvertieren der ersten 4 Zeichen des neu reservierten Speichers in einen PChar erhältst.

Ist das nur bei PChar so oder auch bei anderen Typen?
Zitat:
Die richtige Konvertierung wäre PChar(Puffer) (ohne das "^"-Zeichen)

Komischerweise bekomme ich grad hier die Schutzverletzung :?: Wenn ich die Pointer richtig verstanden hab steht in Puffer die Adresse. Setzt ich ein ^ ran kann ich lesen und schreiben darin. Da in meinem Fall Puffer untypisiert ist, muß ich ihn vorher typisieren.
Also
ausblenden Delphi-Quelltext
1:
PChar(Puffer^) :=					

das funktioniert jedenfalls bei mir

Gruß Thomas
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Di 24.06.03 21:13 
Bei PChars kannst du nicht einfach den Zuweisungsoperator (":=") benutzen. Dieser würde nämlich die Zeiger-Adresse auf die Adresse setzen, an der der Compiler den String abgelegt hat.

Dein Code muss also
ausblenden Delphi-Quelltext
1:
StrCopy(PChar(Puffer), ''Testtext');					

lauten.

Um noch einmal auf die Typenkonvertierung zurückzukommen.

Puffer -> $1000
An Speicheradresse $1000 steht: $00 01 02 03 04 05

Mit PChar(Puffer^) machst du nun folgendes:
ausblenden Delphi-Quelltext
1:
2:
var P: PChar;
  P := $00 01 02 03;

Damit zeigt der neugewonnene Zeiger P nicht auf den reservierten Speicherplatz, sondern wild in den Arbeitsspeicher.


Bei PChar(Puffer^) := 'Testtext'; überschreibst du die ersten 4 Bytes des Speichers, auf den Puffer zeigt. Dadurch wird aus den oben genannen $00 01 02 03 die Adresse an der der Compiler 'Testtext' abgelegt hat. Es ist dann natürlich kar, dass du mit ShowMessage(PChar(Puffer^)) die Adresse von 'Testtext' übergibst. Damit brauchst du gar nicht 255 Bytes reservieren, wenn du sowieso nur 4 davon nutzt.

Das 1. Beispiel kannst du auch so lösen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var Puffer: PChar;
begin
  Puffer := 'Testtext'// Adresse von 'Testtext' dem Zeiger Puffer zuweisen
  ShowMessage(Puffer);
end;





Bei deinem 2. Beispiel machst du bei der Ausgabe den selben Fehler (vom Schreibfehler PPuffer mal abgesene).

Die Funktion GetLogicalDriveStrings() schreibt die Daten in den ihr übergebenen PChar, wobei hier zu beachten ist, dass die einzelnen Teilstring mit einem #0-Zeichen von einander getrennt sind. Nach dem letzen Teilstring kommt ein #0#0, dass den gesamten String abschließt.
Wenn du nun PChar(Puffer) an ShowMessage übergibst, gibt diese nur den ersten Laufwerksbuchstaben aus, da das erste #0 als Stringende betrachtet wird. Das noch weitere Laufwerksbuchstaben folgen, kann ShowMessage nicht wissen. Dies muss der Programmierer erledigen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
var
  P: PChar;
  S: string;
begin
  P := StrAlloc(255 + 1);
  try
    GetLogicalDriveStrings(255, P);
    while P^ <> #0 do
    begin
      SetString(S, P, StrLen(P));
      P := StrEnd(P) + 1// auf nächsten Laufwerksbuchstaben setzen.

      ShowMessage(S);
    end;
  finally
    StrDispose(P);
  end;
end;

_________________
Ist Zeit wirklich Geld?
Thomas_1110 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win Vista
Delpi 7 Personal
BeitragVerfasst: Di 24.06.03 21:45 
Danke für die Mühe, da muß ich noch viel lernen zum Thema Pointer :roll:
Bei deinem Beipiel muß man noch den Zeiger wieder auf den Ursprung setzten, sonst gibts am Schluß eine Fehlermeldung.
Gruß Thomas
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Fr 27.06.03 19:13 
Thomas_1110 hat folgendes geschrieben:
Danke für die Mühe, da muß ich noch viel lernen zum Thema Pointer :roll:

Dann schau dir mal das Pointer-Tutorial an (hier in der Tutorial-Sparte).

@AndyB: was PChars und deren Typecastings betrifft so führt Delphi im Hintergrund oft noch zusätzliche Schritte aus! Bestes Beispiel sind die 3 verschiedenen Methoden einen String in einen PChar zu casten:
ausblenden Delphi-Quelltext
1:
2:
3:
PChar(String)
@String[1]
Pointer(String)

mit jeder dieser Methoden kann man einen String in einen PChar casten, aber immer mit einem andren Ergebnis!

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Thomas_1110 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win Vista
Delpi 7 Personal
BeitragVerfasst: Fr 27.06.03 20:16 
Zitat:
Dann schau dir mal das Pointer-Tutorial an (hier in der Tutorial-Sparte).

Danke für den Tip, hab ich schon gelesen, ist aber nur ein Teil von dem was das Thema zu bieten hat.

Gruß Thomas
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Fr 27.06.03 20:25 
Das stimmt schon, aber die wichtigsten Sachen werden darin bereits erklärt (referenzieren, dereferenzieren, ...) der Rest sind Details die man eh nur per learning by doing wirklich lernen kann...

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!