Jump to content
santiago

TObject.NewInstance, TObject.InitInstance, GetMem and Pointer address

Recommended Posts

Hi there,

 

when a TObject is instantiated, the following function is called: TObject.NewInstance: TObject;

 

The code in this function is straightforward. It calls GetMem with the InstanceSize to allocate the necessary memory for the object.
GetMem returns a pointer to the allocated memory space.

class function TObject.NewInstance: TObject;
begin
  Result := InitInstance(_GetMem(InstanceSize));
{$IFDEF AUTOREFCOUNT}
  Result.FRefCount := 1;
{$ENDIF}
end;

The pointer to the allocated memory is passed to TObject.InitInstance(Instance: Pointer): TObject;

This function is implemented in assembler. I do not understand what happens here.

 

I am struggling to understand the relationship between the memory address returned by GetMem and the pointer address of the instantiated TObject.

 

Look at this very simple code:

 

DummyObject := TObject.Create;  // DummyObject is declared as TObject
DummyPointer := @DummyObject;  // DummyPointer is declared as Pointer

For example:

With the debugger I can see that the call to GetMem returned the address: 04AEFA60  (in decimal 78576224)

But DummyPointer is pointing to the following address: 69FC6BE0 (in decimal 1778150368)

The addresses are completely unrelated.

 

Does anyone have an explanation for this?

I tried the same with TStringList. The GetMem address and the pointer address are also completely different. The delta between them is also different than the TObject delta.

 

However for objects derived from TInterfacedObject there is a constant delta of 12 bytes, between the GetMem address and the pointer address.

 

Why do I need this?

 

I have the GetMem address which was used to instantiate a given object.

I need to be able to convert the GetMem address to the object pointer address. That way I can obtain a reference to the TObject which I can then Rtti inspect.

 

Thank you!

 

 

 

 

 

Share this post


Link to post
Guest

DummyObject is a variable which can contain a value of an object reference. This variable value has to be stored somewhere in memory. And DummyPointer is the address where the DummyObject value is stored.

Share this post


Link to post
1 hour ago, Schokohase said:

DummyObject is a variable which can contain a value of an object reference. This variable value has to be stored somewhere in memory. And DummyPointer is the address where the DummyObject value is stored.

Thanks, got it!

What I needed to do was:

 

DummyPointer := Pointer(DummyObject);

 

 

Share this post


Link to post
On 6/1/2019 at 1:57 PM, santiago said:

The pointer to the allocated memory is passed to TObject.InitInstance(Instance: Pointer): TObject;

This function is implemented in assembler. I do not understand what happens here.

InitInstance() fills the allocated memory with zeros and inserts a pointer to the class's vtable at the front of the memory

 

On 6/1/2019 at 4:51 PM, santiago said:

What I needed to do was:


DummyPointer := Pointer(DummyObject);

You should not need the type cast.  ANY pointer can be assigned as-is to an untyped Pointer variable/parameter.

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×