PChar

解決


ぴーちゃー  2005-04-12 02:13:32  No: 14259

FindWindow(nil,PChar('....'))
のようなばあいのPCharは開放しなくていいのでしょうか?


メラトニン  2005-04-12 03:06:02  No: 14260

ヘルプに

PChar の処理でよく見られる誤りは,ローカル変数をデータ構造に格納したり,ローカル変数を値として返すことです。PChar は参照カウントされる文字列のコピーではなくメモリへのポインタなので,ルーチンの終了時に削除されます。

とあるのでこれを鵜呑みにすると開放の必要は無いようです。


りおりお  2005-04-12 03:37:05  No: 14261

その例では、単にキャストしてるだけですから、開放とか考える必要はまったくありません。

ちなみに、PChar('....') はまったく無意味です。(分かりやすいから無意味でもないか)
文字列リテラルは PChar と互換性がありますから、

FindWindow(nil,'....');

でOKです。


ぴーちゃー  2005-04-18 01:18:20  No: 14262

わかりました。
ありがとうございました。
>PChar は参照カウントされる文字列のコピーではなくメモリへのポインタなので,ルーチンの終了時に削除されます。
パスカル文字列にNULLはないのに、どのようにしてコピーせずに文字列をPChar(の参照先?)として認識してるのでしょうか?(特にPChar(string型変数)みたいなとき)
それと、P:=PChar('')みたいにしたときは開放されませんでした。
Xxx(PChar('....'))みたいなときは調べようがないので質問させていただきました。
サンプルソースなどでもよくある記述なので問題ないようです。
ありがとうございました。


りおりお  2005-04-18 04:17:40  No: 14263

> どのようにしてコピーせずに文字列をPChar(の参照先?)として認識してるのでしょうか?

ちょっと、以下のコードを試してみてください。

procedure TForm1.Button1Click(Sender: TObject);
var
  s:string;
  p:PChar;
begin
   s := 'ピーチャーって何だ?';
   Label1.Caption := 'string 型の変数のサイズは '+IntToStr(SizeOf(s));

   Label2.Caption := 's[1] のアドレスは '+IntToStr(Cardinal(@s[1]));
   Label3.Caption := '変数 s の中身は '+IntToStr(Cardinal(s));

   p := PChar(s);

   Label4.Caption := ' p の値は '+IntToStr(Cardinal(p));
end;

結果を見ると、

1.string 型の変数のサイズは4バイトであり、文字列の先頭の文字を指すポインタである。
2.PChar(s) のようなコードは、string 型の変数が保持している値を PChar にキャストしているだけ。

が分かります。キャストではなく、明示的に PChar 型の変数にメモリを割り当てるときは、以下のようにします。

procedure TForm1.Button2Click(Sender: TObject);
var
  p:PChar;
  s:string;
  Wnd:HWND;
begin
  s := 'notepad';
  GetMem(p,Length(s)+1);// #0 までコピーする
  try
    Move(s[1],p^,Length(s)+1);
    Wnd := FindWindow(p,nil);
    Label5.Caption := IntToStr(Wnd);
  finally
    FreeMem(p);
  end;
end;

このように、明示的にメモリを確保したときは、明示的に開放しなければなりません。


pi-cha-  2005-04-18 06:02:20  No: 14264

AnsiString型変数自体は4バイトでデータそのものではないというのは聞いたことがありましたが、PCharと全く?同じことだったんですね。
それならキャストも出来ますね
よくわかりました。
ありがとうございました。


ぴーちゃー  2005-04-18 06:03:09  No: 14265

名前入力時半角になっててEnterで誤送信してしまいました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加