vfrc
asked on
Dynamical arrays
I have a record. But I want create an array of this record. Size of this array not determine. I want increaze size of my array in code.
Sorry for bad english. Max.
Sorry for bad english. Max.
Sorry,
mArray=Array of MyRecordType
mArray=Array of MyRecordType
vfrc,
here is the example I once got from inter :
Good day(or night) friends,
I'd like to give an example about dynamic allocation and range checking off...
Simply start with a new form and paste the following code and link the FormCreate method to the
one below.
//CODE BEGINS
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
PTestRec = ^TTestRec;
TTestRec = packed record
x : integer;
y : array[0..0] of char;
end; var
Form1: TForm1;
implementation
{$R *.DFM}
// turn range checking off so that we can access ttestrec.y[0...n]
{$R-} procedure TForm1.FormCreate(Sender: TObject);
var
p : PTestRec; //declare a pointer
i : integer; begin
GetMem(p, sizeof(TTestRec) + 20);
try
i :=5;
StrCopy(p.y, 'hello there');
Caption := StrPas(PChar(@(p.y[i])));
finally
FreeMem(p, sizeof(TTestRec) + 20);
end; end;
end.
// CODE ENDS
WHAT IS UP
--------------
Our record decleration is as follows(just an example)
PTestRec = ^TTestRec;
TTestRec = packed record
x : integer;
y : array[0..0] of char;
end;
Now assume that, I want to place a null terminated string in y and feed to some function. Now let's analyze the code at
formcreate(follow my comments)
{$R-}
procedure TForm1.FormCreate(Sender: TObject);
var
p : PTestRec;
i : integer; begin
// now this is dynamic allocation. By doing this
// I have a record at p which indirectly means as follows
// TTestRec = packed record
// x : integer;
// y : array[0..20] of char;
// end;
GetMem(p, sizeof(TTestRec) + 20);
try
i :=5; // we should use a variable to address the p.y[i]
// note that p.y[1] produces and error at COMPILE TIME
StrCopy(p.y, 'hello there'); //no GPFault! we succeeded
Caption := StrPas(PChar(@(p.y[i]))); //forms caption should be 'there'
finally
FreeMem(p, sizeof(TTestRec) + 20);
end; end;
To test it put a break point at formcreate and run the program. Step and debug the p and its members...
So, is it clear?
Regards, Igor
Regards, Zif.
ps. all thanks to inter.
here is the example I once got from inter :
Good day(or night) friends,
I'd like to give an example about dynamic allocation and range checking off...
Simply start with a new form and paste the following code and link the FormCreate method to the
one below.
//CODE BEGINS
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
PTestRec = ^TTestRec;
TTestRec = packed record
x : integer;
y : array[0..0] of char;
end; var
Form1: TForm1;
implementation
{$R *.DFM}
// turn range checking off so that we can access ttestrec.y[0...n]
{$R-} procedure TForm1.FormCreate(Sender: TObject);
var
p : PTestRec; //declare a pointer
i : integer; begin
GetMem(p, sizeof(TTestRec) + 20);
try
i :=5;
StrCopy(p.y, 'hello there');
Caption := StrPas(PChar(@(p.y[i])));
finally
FreeMem(p, sizeof(TTestRec) + 20);
end; end;
end.
// CODE ENDS
WHAT IS UP
--------------
Our record decleration is as follows(just an example)
PTestRec = ^TTestRec;
TTestRec = packed record
x : integer;
y : array[0..0] of char;
end;
Now assume that, I want to place a null terminated string in y and feed to some function. Now let's analyze the code at
formcreate(follow my comments)
{$R-}
procedure TForm1.FormCreate(Sender: TObject);
var
p : PTestRec;
i : integer; begin
// now this is dynamic allocation. By doing this
// I have a record at p which indirectly means as follows
// TTestRec = packed record
// x : integer;
// y : array[0..20] of char;
// end;
GetMem(p, sizeof(TTestRec) + 20);
try
i :=5; // we should use a variable to address the p.y[i]
// note that p.y[1] produces and error at COMPILE TIME
StrCopy(p.y, 'hello there'); //no GPFault! we succeeded
Caption := StrPas(PChar(@(p.y[i]))); //forms caption should be 'there'
finally
FreeMem(p, sizeof(TTestRec) + 20);
end; end;
To test it put a break point at formcreate and run the program. Step and debug the p and its members...
So, is it clear?
Regards, Igor
Regards, Zif.
ps. all thanks to inter.
hi vfcr,
here a sample in old pascal-code(simple List), it also works in delphi-code
type
YourRecord = record
YourRecordEntries;
end;
type
YourRecordPointer = ^YourRecordList;
YourRecordList = Record
YR : YourRecord;
Next : YourRecordPointer;
end;
var
rootptr : YourRecordPointer = nil; {holds the start of the list}
tmpptr : YourRecordPointer = nil; {temporary for free use (search, create, delete)}
topptr : YourRecordPointer = nil; {holds the top of the list}
procedure addrecord(ARecord : YourRecord);
begin
new(tmpPtr);
tmpptr^.YR := ARecord;
tmpptr^.next := nil;
{ First Entry ?}
if rootptr = nil then rooptr := tmpptr;
if topptr = nil then
topptr := tmpptr
else
begin {No First Entry}
topptr^.next := tmpptr;
topptr := tmpptr;
end;
end;
procedure deletedynlist;
begin
tmpptr := rootptr;
while tmpptr <> nil do
begin
rootptr := tmpptr^.next;
dispose(tmpptr);
tmpptr := rootptr;
end;
end;
there can be more procedures as sortlist or deleteentry or searchrecord and so on
meikl
here a sample in old pascal-code(simple List), it also works in delphi-code
type
YourRecord = record
YourRecordEntries;
end;
type
YourRecordPointer = ^YourRecordList;
YourRecordList = Record
YR : YourRecord;
Next : YourRecordPointer;
end;
var
rootptr : YourRecordPointer = nil; {holds the start of the list}
tmpptr : YourRecordPointer = nil; {temporary for free use (search, create, delete)}
topptr : YourRecordPointer = nil; {holds the top of the list}
procedure addrecord(ARecord : YourRecord);
begin
new(tmpPtr);
tmpptr^.YR := ARecord;
tmpptr^.next := nil;
{ First Entry ?}
if rootptr = nil then rooptr := tmpptr;
if topptr = nil then
topptr := tmpptr
else
begin {No First Entry}
topptr^.next := tmpptr;
topptr := tmpptr;
end;
end;
procedure deletedynlist;
begin
tmpptr := rootptr;
while tmpptr <> nil do
begin
rootptr := tmpptr^.next;
dispose(tmpptr);
tmpptr := rootptr;
end;
end;
there can be more procedures as sortlist or deleteentry or searchrecord and so on
meikl
hi vfrc,
i forget the topptr
procedure deletedynlist;
begin
tmpptr := rootptr;
while tmpptr <> nil do
begin
rootptr := tmpptr^.next;
dispose(tmpptr);
tmpptr := rootptr;
end;
Topptr := nil;
end;
meikl
i forget the topptr
procedure deletedynlist;
begin
tmpptr := rootptr;
while tmpptr <> nil do
begin
rootptr := tmpptr^.next;
dispose(tmpptr);
tmpptr := rootptr;
end;
Topptr := nil;
end;
meikl
Another way is by the use of TList (available even for Delphi 1.0)
http://www.delumpa.com/
Look in the tips section to learn how to use dynamic arrays if you don't have Delphi 4.
Look in the tips section to learn how to use dynamic arrays if you don't have Delphi 4.
But if you HAVE Delphi 4, please please please use it's dynamic arrays. You can dynamically change the array size by using SetLength(array,arrayLen). ..
Regards, Madshi.
Regards, Madshi.
Some of us are handicapped!! Some of us only have Delphi 2!! (Are we classified as Delphi Gimps?) :)
Yes, you are... :-)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hello?
Tim.
Tim.
mArray:Array of MyRecordType;
With no range defined, you can increase the size dynamically in code.