1

次の関数で「レコード」タイプのサイズを取得したい。しかし、うまくいかないようです:

function GetDataSize(P : Pointer) : Integer;
begin
  Result := SizeOf(P^); // **How to write the code?**
end;

たとえば、次のレコードのサイズは 8 バイトです。

SampleRecord = record
 Age1 : Integer;
 Age2 : Integer;
end;

ただし、GetDataSize(@a)常に 1 を返します (a はもちろん SampleRecord 型の変数です)。私は何をすべきか?

Delphi には、 P が指す型のサイズに対応するメモリ ブロックを割り当てることができるプロシージャprocedure New(var P: Pointer)があることに気付きました。どのようにサイズを取得できますか?

4

4 に答える 4

7

New割り当てるメモリの量がわかっている理由Newは、コンパイラの魔法です。これは組み込みの言語であるため、コンパイラーは、ユーザーがそれを呼び出していることを確認すると、次のように書き換えます。

// New(foo);
foo := System._New(SizeOf(foo^), TypeInfo(TypeOf(foo^)));

TypeOfこれは、説明のために作成されたDelphi関数です。コンパイラはfoo、すべての変数宣言がどこにあるかを知っているため、の宣言された型を知っています。System.pasでの実装を見ることができ_Newます。同様の書き換えが発生するため、メモリを解放する前にどのようなファイナライズを実行するかがわかります。Dispose

変数宣言の概念は、コンパイル時の概念です。実行時に、それらは存在しなくなります。実行時には、ポインタは単なるアドレスです。それが指すもののタイプは、コンパイル時に決定されました。タイプは何かのサイズを決定するものです。

サイズの異なる複数のものへのポインターを受け入れる関数を作成する必要がある場合は、最初のパラメーターが何を指しているかを説明する2番目のパラメーターを指定する必要があります。

ここで別の質問「varがどのタイプであるかを知る方法」を確認してください。質問者は、そのアドレスのみが与えられた変数に関する詳細情報をどのように決定するのか疑問に思いました。

于 2009-06-09T14:20:02.657 に答える
3

ポインター型の変数を使用してデータ構造のサイズを見つけることはできません。これは、ポインターが考えられるデータ型を指すことができるため、コンパイラーが推測してチェックすることができないためです。ここでいくつかの情報を読むことができます。

于 2009-06-09T10:09:23.350 に答える
2

ポインタが指すレコードのサイズを安全に判断する方法はありません。ただし、ポインタが指すメモリを割り当てた場合は、そのメモリ ブロックのサイズを確認できます。しかし、そのブロックを割り当てたので、そのブロックのサイズはすでにわかっているはずです! Delphi メモリ マネージャは、割り当てられたすべてのメモリ ブロックを追跡します。ポインタがメモリ ブロックの先頭を指している場合、メモリ マネージャからの情報を使用して、この情報を見つけることができます。ただし、メモリの大きなブロックを割り当て、そこにデータをロードし、ポインターがこのブロック内のデータを指している場合、この方法はまったく信頼できません。

また、レコードで参照される型 (動的配列、文字列、クラスなど) を使用する場合、返されるサイズは、データのサイズではなく参照のサイズ (4 バイト) を取得するため、使用できません。を参照しています。

NEW() コマンドは、渡したデータ型の型情報を使用してサイズを取得します。これがどのように行われるかを正確に知るには、Delphi のソースコードを確認してください。\source\Win32\rtl\sys\System.pas を開き、「_New」を検索します。(その前にアンダースコアを付けます。ソースコードは非常に複雑になる可能性がありますが、このソースコードを使用すると、Delphi がメモリ割り当てを処理する方法を理解するのに役立つ場合があります。

于 2009-06-09T11:53:43.483 に答える
0

Delphi にはメモリ マネージャが組み込まれています。newはヒープ オブジェクトにアクセスし、HeapSize() (または同様のルーチン) を使用して、いくつかのポインターのブロックのサイズを取得すると思います。

于 2009-06-09T09:45:31.277 に答える