FindWindow(nil,PChar('....'))
のようなばあいのPCharは開放しなくていいのでしょうか?
ヘルプに
PChar の処理でよく見られる誤りは,ローカル変数をデータ構造に格納したり,ローカル変数を値として返すことです。PChar は参照カウントされる文字列のコピーではなくメモリへのポインタなので,ルーチンの終了時に削除されます。
とあるのでこれを鵜呑みにすると開放の必要は無いようです。
その例では、単にキャストしてるだけですから、開放とか考える必要はまったくありません。
ちなみに、PChar('....') はまったく無意味です。(分かりやすいから無意味でもないか)
文字列リテラルは PChar と互換性がありますから、
FindWindow(nil,'....');
でOKです。
わかりました。
ありがとうございました。
>PChar は参照カウントされる文字列のコピーではなくメモリへのポインタなので,ルーチンの終了時に削除されます。
パスカル文字列にNULLはないのに、どのようにしてコピーせずに文字列をPChar(の参照先?)として認識してるのでしょうか?(特にPChar(string型変数)みたいなとき)
それと、P:=PChar('')みたいにしたときは開放されませんでした。
Xxx(PChar('....'))みたいなときは調べようがないので質問させていただきました。
サンプルソースなどでもよくある記述なので問題ないようです。
ありがとうございました。
> どのようにしてコピーせずに文字列を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;
このように、明示的にメモリを確保したときは、明示的に開放しなければなりません。
AnsiString型変数自体は4バイトでデータそのものではないというのは聞いたことがありましたが、PCharと全く?同じことだったんですね。
それならキャストも出来ますね
よくわかりました。
ありがとうございました。
名前入力時半角になっててEnterで誤送信してしまいました。
ツイート | ![]() |