Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Delphi7中获取对象的分配地址_Delphi_Delphi 7 - Fatal编程技术网

在Delphi7中获取对象的分配地址

在Delphi7中获取对象的分配地址,delphi,delphi-7,Delphi,Delphi 7,我有以下代码序列: program OverrideAfterConstructionEtc; {$APPTYPE CONSOLE} uses SysUtils, Classes; type TA = class( TInterfacedObject) public procedure AfterConstruction; override; procedure BeforeDestruction; override; protected FDummyData: array[ 1 .

我有以下代码序列:

program OverrideAfterConstructionEtc;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes;

type

TA = class( TInterfacedObject)
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
protected
FDummyData: array[ 1 .. 1000 ] of longint;
end;

{ TA }

procedure TA.AfterConstruction;
var
    selfPtr: Pointer;
    selfInt: Integer;
    selfStr: string;
    size: Integer;
begin
    inherited AfterConstruction;
    selfPtr := Addr( self );
    selfInt := Integer( selfPtr );
    selfStr := IntToHex( selfInt, 8 );

    size := TA.InstanceSize;
    WriteLn( 'TA instance allocated at 0x', selfStr );
    WriteLn( 'TA size is ', size );


end;

procedure TA.BeforeDestruction;
var
    selfPtr: Pointer;
    selfInt: Integer;
    selfStr: string;

    size: Integer;

begin

    selfPtr := Addr( self );
    selfInt := Integer( selfPtr );
    selfStr := IntToHex( selfInt, 8 );

    WriteLn( 'Preparing to destroy TA instance allocated at 0x', selfStr );

    size := TA.InstanceSize;
    WriteLn( 'TA size is ', size );

    inherited BeforeDestruction;
end;

const
    maxDummy = 1000;
var
    a: TA;
    dummy: TList;
    iter : integer;

    dummies: array [ 1 .. maxDummy ] of TList;
begin

    // Simulate a set of allocations.

    for iter := 1 to maxDummy do
    begin
        dummy := TList.Create;
        dummies[ iter ] := dummy;
    end;

    // Allocate the object we want to track.
    a := TA.Create;

    // Release the simulated allocations.
    for iter := 1 to maxDummy do
    begin
        dummy := dummies[ iter ];
        dummies[ iter ] := nil;
        FreeAndNil( dummy );
    end;



    // Release the tracked object.

    FreeAndNil( a );

end.
代码的输出为:

  • 在0x0012FF88分配的TA实例
  • TA的大小是4012,准备销毁
  • 在0x0012FF80分配的TA实例
  • TA的尺寸是4012

我不理解“自我”的区别。你能给我一个提示吗?我希望打印的值是相同的。

以下代码将为您提供解释:

type
  TA = class( TInterfacedObject)
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
  end;

procedure TA.AfterConstruction;
begin
  inherited;
  writeln('AfterConstruction=',integer(self));
  writeln('AfterConstruction=',integer(addr(self)));
end;

procedure TA.BeforeDestruction;
begin
  writeln('BeforeDestruction=',integer(self));
  writeln('BeforeDestruction=',integer(addr(self)));
  inherited;
end;
以下是输出:

AfterConstruction=10731904
AfterConstruction=1245020
BeforeDestruction=10731904
BeforeDestruction=1245028
所以整数(self)是正确的(两个值都等于10731904),但整数(addr(self))不是

因为addr(self)不显示self值,而是显示self值的存储位置

在这两种情况下,它都存储在堆栈中(使用Alt-F2分解这两种方法的前缀):

因此,当您使用addr(self)时,您查看的是当前堆栈地址,而不是self值

Addr不是指向指针的简单类型转换,但与@self相同,因此使用integer(self)与integer(Addr(self))不同


不应使用Addr(self)而应使用self来查找对象的分配地址。

self
在实例方法中是一个隐式参数,是对接收方法调用的实例的引用。它是作为指针实现的

Addr
标准程序与
@
操作员相同;它获取传递给它的位置的地址。当您将
Addr
应用于
Self
时,您将获得参数位置的地址,而不是实例的地址。此参数位置在堆栈上分配,因为它只需要在方法调用处于活动状态时存在;当方法调用返回时,不再需要
Self
参数的空间;CPU的堆栈指针移回调用该方法之前的位置,从而隐式释放该方法


Self
参数可能位于同一实例上不同方法调用中的不同位置的原因是,调用时堆栈上可能有更多或更少的数据。例如,如果方法调用序列看起来像
A->B->C
而不是
A->C
,则
Self
参数的分配将不同,因为
B
的堆栈帧需要存储在
A
C
的堆栈帧之间。堆栈框架是分配与方法的任何给定调用相关联的参数和局部变量的地方。

谢谢您的回答。我如何将它们都标记为答案(web UI只允许我选择其中一个)?@Dan我想你只能选择一个!就这么定了!:)
mov [esp],eax