Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi PChar ??? (https://www.delphipraxis.net/101796-pchar.html)

edeWelzheim 18. Okt 2007 08:16


PChar ???
 
die Aufgabe:
in einer ISR sollen seriell eintreffende Daten zeichenweise verarbeitet werden.
der Empfangspuffer ist definiert als zB ch:array[0..1] of char.
natürlich möchte ich die Zeichen zusammenfügen, am einfachsten natürlich so:
s:= s + ch[0]
aus unerfindlichen (noch unbekannten) Gründen stürzt der PC *bei dieser* Anweisung ab, weshalb
ich auf die Idee kam, die Zeichen eben als PChar zu verwalten, was aber wieder andere
Schwierigkeiten aufwirft:
in den knappen Beschreibungen, die ich habe, sieht alles ganz klar + einfach aus, wenngleich es
auch Widersprüche gibt (zB 'PChar nur Zeiger, vor der Arbeit muss Speicher res werden' - eine andere Quelle weist einfach Inhalt zu; oder: 'StrPCopy nur im Zus'hang mit ShortStrings zu verwenden' - andere Quelle nutzt diese Routine mit normalen Strings + array of char).

Habe nun ein Mini-Test-Pogramm gemacht, das aber die unmöglichsten Ergebnisse bringt (eigentlich
immer etwas anderes als erwartet); besonders übel (ges-Zus'hang s.u.):
1)
//s:=Edit1.Text; pCh:=strPCopy(x,s); {->nicht ok; Müll hinten dran..?}
2)
{pCh:=strCat(pCh,pCh);} {ergibt 'ungültige Zeigeroperation' ?}
3)
//das folgende tut auch nicht.. ?}
s:=inttoStr(StrLen(pCh));{StrPas(pCh);} Label1.Caption:=s;


Kann da vielleicht jemand für Klarheit sorgen?? Danke!


PS:
a) wird strAlloc überhaupt benötigt?
b) wie gesagt: eigentlich möchte ich nur Char/PChar aneinanderreihen (analog s:=s+'x');



[code]
unit Test_PChar;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;

type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
ChArray:array[0..100] of char;
pCh:PChar;
ChArray2:array[0..100] of char;
pCh2:PChar;
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var i,j,k:integer; x:array[0..10] of char;
pX:PChar;
begin
pX:=x; {nur ok, wenn x-Array ab '0'!!}
//sonst Compiler-Err 2010 (inkompatible Typen Array and PAnsiChar)
{pCh:=@ChArray;}
pCh:='123';
{pCh2:=@ChArray2;}
pCh2:='456';
Label1.Caption:=StrPas(pCh);
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var pHlp:PChar;
x:array[0..100] of char;
s:string;
begin
{pHlp:=strAlloc(100);}
//s:=Edit1.Text; pCh:=PChar(s); {->ist ok}
//s:=Edit1.Text; pCh:=strPCopy(x,s); {->nicht ok; Müll hinten dran..?}
pCh :=strPCopy(ChArray,Edit1.Text);
pHlp:=strPCopy(ChArray2,Edit2.Text);
pCh:=strCat(pCh,pCh2);
s:=Edit2.Text; pCh2:=PChar(s); {->ist ok}
{pCh:=strCat(pCh,pCh);} {ergibt 'ungültige Zeigeroperation' ?}
//das folgende tut auch nicht.. ?}
s:=inttoStr(StrLen(pCh));{StrPas(pCh);} Label1.Caption:=s;
{StrDispose(pHlp);}
end;

end.

jbg 18. Okt 2007 11:25

Re: PChar ???
 
Um Gotteswillen.

Zitat:

Zitat von edeWelzheim
in den knappen Beschreibungen, die ich habe, sieht alles ganz klar + einfach aus, wenngleich es
auch Widersprüche gibt

Das sind keine Widersprüche, sonder die Tatsache, dass ein PChar auf den selben Speicherbereich zeigen kann, wie ein String. Änderst du die Daten über den PChar, ändern sich automatisch auch die Daten des Strings. Das kann, wenn man nicht weiß, was man tut, gefährlich werden.

Zitat:

1)
//s:=Edit1.Text; pCh:=strPCopy(x,s); {->nicht ok; Müll hinten dran..?}
Lass mich raten. Der "Müll" steht hinter einem #0-Zeichen, also nicht im String, sondern einfach in den nicht benutzen Elementen des Arrays.

Zitat:

2)
{pCh:=strCat(pCh,pCh);} {ergibt 'ungültige Zeigeroperation' ?}
Das lasse ich jetzt mal unkommentiert.

Zitat:

3)
//das folgende tut auch nicht.. ?}
s:=inttoStr(StrLen(pCh));{StrPas(pCh);} Label1.Caption:=s;
Kann es sein, dass pCh ins Nirvana zeigt?


Zitat:

PS:
a) wird strAlloc überhaupt benötigt?
Das kommt darauf an, wie du an die Sache herangehst. Im Moment mischt du da kräftig durcheinander.
Zitat:

b) wie gesagt: eigentlich möchte ich nur Char/PChar aneinanderreihen (analog s:=s+'x');
PChars kann man nicht aneinanderreihen, da es Zeiger sind. Oder wie würdest du Zeiger aneinanderreihen? (außer vielleicht in einem Array)


Zitat:

pCh:='123';
Damit zeigt pCh auf den konstanten string '123', der insgesamt 4 Bytes enthält '123'#0. Wenn du nun versuchst da noch was anzuhängen, überschreibst du Speicher. Das ist auch als "Buffer Overflow" bekannt.



Mein Tipp: Schmeiß alles weg und probiere es ohne PChars nochmal.

edeWelzheim 18. Okt 2007 14:23

Re: PChar ???
 
Danke!
mit deinen Anmerkungen zur Seite bin ich noch mal in mich gegangen + hab nun die
Zusammenhänge kapiert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:07 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