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 ^.
精彩评论