开发者

delphi pointer question

I have the following code which is working, but I don't understand it 100% (please see the comments from code):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TMyRec=record
    a:Integer;
    b:String;
  end;
  TRecArray=array of TMyRec;
  PRecArray = ^TRecArray;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
   v1:TRecArray;
   procedure Test(a:PRecArray);
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
 SetLength(v1,3);
 v1[0].b:='test1';//set the first value
 Test(PRecArray(v1));//call method to change the value assigned before
end;

procedure TForm1.Test(a: PRecArray);
begin
 ShowMessage(v1[0].b);//shows test1
 try
  a^[0].b:='test2' //this is raising an error...
 except

 end;
 PRecArray(@a)^[0].b:='test3';//this is working...
 ShowMessage(v1[0].b);//shows test3
end;

end.

I don't understand why 'a^[0].b:='test2' is raisin开发者_JAVA技巧g an error.

Thank you!


Your 'Test' procedure expects a 'PRecArray', but you're passing a 'TRecArray' to it. Try calling it like

 Test(@v1);//call method to change the value assigned before

Typecasting a 'TRecArray' to a 'PRecArray' will not make it a 'PRecArray'. (Note: your 'test3' will fail then of course.)


I see several things that are suspicious.

1

There is hardly ever a need to take a pointer to a dynamic array, as dynamic array variables are already pointers (well, references).

To pass such an array to a function or procedure, use var parameters:

procedure TForm1.Test(var a: TRecArray);

Now you don't have to use pointer syntax to access the array:

a[0].b := 'test2';

2

You call Test with:

Test(PRecArray(v1));

In your original, Test took a PRecArray, but you are not passing one (you are passing a TRecArray), so you should have done:

Test(@v1); // or Test(Addr(v1));

Applying my change above, where Test has a var parameter, simply use:

Test(v1);

3

Ok, this is probably not suspicous, but I'd like to plug my article Addressing Pointers, about pointers for Delphi programmers. It explains many of the issues you seem to have.


You could replace the

procedure TForm1.Test(a: TPointerArrayRec);

with

   procedure TForm1.Test(var a: TArrayRec);   

it's simpler and you don't have to use the deprecation dereference operator ^.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜