Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2002-09

More of a FPC question but... dynamic arrays

9 messages · 5 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Tony Maro

In Delphi 4 I used dynamically sized arrays using setlength to resize them as needed.

I haven't been able to get it to work in FPC / Lazarus, and it looks like the setlength function isn't there. In fact, defining the array using:

var
	MyArray: array of TObject;

Doesn't work either...

This was a feature they added in Delphi 4. I've got over 60,000 lines of code that rely heavily on this that I was looking to migrate to Lazarus.

Have I just missed something, or must I write my own linked list manager or use a TCollection to get this to work?

Thanks,
Tony

Reply by email

Andrew Johnson
Show quoted text 15 lines
Type TMyObj = class(TObject) Private FMyArray: ^TMyRecord public procedure Add(MyItem: TMyRecord); procedure Delete(MyIndex: Integer); function Count: Integer; function Items{here's where I lose it - is it Items(Index: Integer)?} end; {Sample usage:} MyObj := TMyObj.Create; MyObj.Add(ThisItem); // adds an item to the array MyItem := MyVar.Items[1]; // grabs the first item on array

the proper way would be to use a Property :

Type TMyObj = class(TObject)
Private
   FMyArray: ^TMyRecord
protected
  Function GetItem(Index : Integer) : TMyRecord;
public
   procedure Add(MyItem: TMyRecord);
   procedure Delete(MyIndex: Integer);
   function Count: Integer;
   property Items[Index: Integer] : TMyRecord read GetItem; Default;
end;

and you would put the actual routine in GetItem. The default allows you to read like myobj[0], aka you don't have to do a myobj.items[0]

Andrew

_________________________________________________________________ Join the world�s largest e-mail service with MSN Hotmail. http://www.hotmail.com

Reply by email

Andrew Johnson
Show quoted text 18 lines
In Delphi 4 I used dynamically sized arrays using setlength to resize them as needed. I haven't been able to get it to work in FPC / Lazarus, and it looks like the setlength function isn't there. In fact, defining the array using: var MyArray: array of TObject; Doesn't work either... This was a feature they added in Delphi 4. I've got over 60,000 lines of code that rely heavily on this that I was looking to migrate to Lazarus. Have I just missed something, or must I write my own linked list manager or use a TCollection to get this to work?

Well this anoyed me to no end when I started working with FPC, but basically Dyn. Arrays don't exist in the FPC 1.0 branch, only in the unstable 1.1 branch. However, C dynamic arrays, aka Pointer arrays, do work. I am guessing you do not know how to do them, but it is really quite simple:

var
  myarray : ^TObject;
begin
  ...//do stuff
  reallocmem(myarray, 4*SizeOf(TObject));//allocmem to handle 4 objects
  myarray[2] := thisobject;//set the 3 entry
  ...//do stuff.
  reallocmem(myarray, 0);//free memory
end;

you simply use reallocmem in place of setlength, and multiply the length by the sizeof the type it contains.. at one point I actually created wrappers arround this to make more like Delphi dynamic arrays..but its been awhile so I do not know if I still have it. essentially though you should be able to port a lot of code with ease. by doing some sort of wrappers.. etc.

Andrew

_________________________________________________________________ MSN Photos is the easiest way to share and print your photos: http://photos.msn.com/support/worldwide.aspx

Reply by email

Tony Maro
to Andrew Johnson
Andrew Johnson wrote 15 lines
var myarray : ^TObject; begin ...//do stuff reallocmem(myarray, 4*SizeOf(TObject));//allocmem to handle 4 objects myarray[2] := thisobject;//set the 3 entry ...//do stuff. reallocmem(myarray, 0);//free memory end; you simply use reallocmem in place of setlength, and multiply the length by the sizeof the type it contains.. at one point I actually created wrappers arround this to make more like Delphi dynamic arrays..but its been awhile so

That's been working great! Thanks...

Next question: How can I return one from an object similar to TStrings? I checked the LCL sources and couldn't figure it out.

Here's what I want:

Type TMyObj = class(TObject)
Private
  FMyArray: ^TMyRecord
public
  procedure Add(MyItem: TMyRecord);
  procedure Delete(MyIndex: Integer);
  function Count: Integer;
  function Items{here's where I lose it - is it Items(Index: Integer)?}
end;
{Sample usage:}
MyObj := TMyObj.Create;
MyObj.Add(ThisItem); // adds an item to the array
MyItem := MyVar.Items[1]; // grabs the first item on array

Thanks!
Tony

Reply by email

Florian Klaempfl
to Tony Maro: In Delphi 4 I used dynamically sized arrays using setlength to resize them as needed. I…
you wrote 18 lines
In Delphi 4 I used dynamically sized arrays using setlength to resize them as needed. I haven't been able to get it to work in FPC / Lazarus, and it looks like the setlength function isn't there. In fact, defining the array using: var MyArray: array of TObject; Doesn't work either... This was a feature they added in Delphi 4. I've got over 60,000 lines of code that rely heavily on this that I was looking to migrate to Lazarus. Have I just missed something, or must I write my own linked list manager or use a TCollection to get this to work?

Did someone try lazarus with 1.1 recently?

Reply by email

Mattias Gaertner
to Tony Maro: In Delphi 4 I used dynamically sized arrays using setlength to resize them as needed. I…
Show quoted text 21 lines
At 03:11 30.09.2002, you wrote: >In Delphi 4 I used dynamically sized arrays using setlength to resize >them as needed. > >I haven't been able to get it to work in FPC / Lazarus, and it looks >like the setlength function isn't there. In fact, defining the array >using: > >var > MyArray: array of TObject; > >Doesn't work either... > >This was a feature they added in Delphi 4. I've got over 60,000 lines >of code that rely heavily on this that I was looking to migrate to >Lazarus. > >Have I just missed something, or must I write my own linked list manager >or use a TCollection to get this to work? Did someone try lazarus with 1.1 recently?

Yes, I do from time to time. The compilation issues changes over time. Currently it has problems with overriden methods of RTTI classes (TPersistent):

graphics.pp(189,15) Warning: An inherited method is hidden by "TFont.Assign(const tagLOGFONTA)"
graphics.pp(188,15) Error: There is no method in an ancestor class to be overridden: "TFont.Assign(TPersistent)"

Both errors make no sense to me.

Mattias

Reply by email

Peter Vreman
Show quoted text 18 lines
In Delphi 4 I used dynamically sized arrays using setlength to resize them as needed. I haven't been able to get it to work in FPC / Lazarus, and it looks like the setlength function isn't there. In fact, defining the array using: var MyArray: array of TObject; Doesn't work either... This was a feature they added in Delphi 4. I've got over 60,000 lines of code that rely heavily on this that I was looking to migrate to Lazarus. Have I just missed something, or must I write my own linked list manager or use a TCollection to get this to work?

The 1.1 development compiler supports dynamic arrays.

Reply by email

Andrew Johnson
Show quoted text 54 lines
On Sun, 2002-09-29 at 20:44, Andrew Johnson wrote: > var > myarray : ^TObject; > begin > ...//do stuff > reallocmem(myarray, 4*SizeOf(TObject));//allocmem to handle 4 objects > myarray[2] := thisobject;//set the 3 entry > ...//do stuff. > reallocmem(myarray, 0);//free memory > end; > > you simply use reallocmem in place of setlength, and multiply the length by > the sizeof the type it contains.. at one point I actually created wrappers > arround this to make more like Delphi dynamic arrays..but its been awhile so > I do not know if I still have it. essentially though you should be able to > port a lot of code with ease. by doing some sort of wrappers.. etc. > > Andrew Andrew (and others): I've successfully been using the above to manage arrays of records, but I finally tried to do objects this way and it won't work. Here's the code snippett: procedure TFrmMain.PrintChecks; var MyPrints: ^TChkTransaction; // array of transactions to print begin writeln('Reallocating memory'); reallocmem(MyPrints, 0); writeln('Zeroed.'); end; Notice, I define a pointer and then attempt to make sure that the array is zero length to begin with (actually I added this just because I was testing why it crashed when I tried to set it the first time.) It access violations before the writeln('Zeroed.') is executed. At this point, I can't think of any reason it would cause a crash. All I have is a pointer and I attempt to reallocate the memory for it... It crashes on reallocmem regardless of the size I specify: reallocmem(MyPrints, 0) and reallocmem(MyPrints,(2 * sizeof(TChkTransaction))) both result in a crash. Am I doing something wrong?

Not exactly.. Basically you are dealing with a Pointer to a Pointer, if you were using ^Pointer or PPointer you would get the same results. I do not know why this make a difference, but it does. Basically this means you need to initialize the variable first with

new(MyPrints);

and finalize when done with

dispose(MyPrints);

Or use a pointer and type cast every time, which is clumsy, so I suggest you do it this way.

Andrew

_________________________________________________________________ Internet access plans that fit your lifestyle -- join MSN. http://resourcecenter.msn.com/access/plans/default.asp

Reply by email

Tony Maro
to Andrew Johnson: On 29 Sep 2002 20:11:42 -0500 Well this anoyed me to no end when I started working with…
Andrew Johnson wrote 17 lines
var myarray : ^TObject; begin ...//do stuff reallocmem(myarray, 4*SizeOf(TObject));//allocmem to handle 4 objects myarray[2] := thisobject;//set the 3 entry ...//do stuff. reallocmem(myarray, 0);//free memory end; you simply use reallocmem in place of setlength, and multiply the length by the sizeof the type it contains.. at one point I actually created wrappers arround this to make more like Delphi dynamic arrays..but its been awhile so I do not know if I still have it. essentially though you should be able to port a lot of code with ease. by doing some sort of wrappers.. etc. Andrew

Andrew (and others):

I've successfully been using the above to manage arrays of records, but I finally tried to do objects this way and it won't work. Here's the code snippett:

procedure TFrmMain.PrintChecks;
var
   MyPrints: ^TChkTransaction; // array of transactions to print
begin
     writeln('Reallocating memory');
     reallocmem(MyPrints, 0);
     writeln('Zeroed.');
end;

Notice, I define a pointer and then attempt to make sure that the array is zero length to begin with (actually I added this just because I was testing why it crashed when I tried to set it the first time.)

It access violations before the writeln('Zeroed.') is executed.

At this point, I can't think of any reason it would cause a crash. All I have is a pointer and I attempt to reallocate the memory for it...

It crashes on reallocmem regardless of the size I specify: reallocmem(MyPrints, 0)
and
reallocmem(MyPrints,(2 * sizeof(TChkTransaction))) both result in a crash. Am I doing something wrong?

-Tony

Reply by email