Sign in Join

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

Mailing lists / fpc-pascal / 2008-11

dynamic arrays behaving funny

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Marc Santhoff

Hi,

I'm trying to assing dynamic array variables to a record type on the heap and handing that record over to the caller:

type
TCompoundInfo = record
		Id: hid_t;
		Name: string;
		TotalSize: longword;
		ElementNames: array of PChar;
		ElementSizes: array of longword;
		ElementTypes: HidTArray;
		ElementOffsets: array of longword;
	end;
PTableInfo = ^TTableInfo;
TTableInfo = TCompoundInfo;
  TBaseCompoundDescriptor = class
  private
    fItemName: string;
    fTotalTypeSize: longword;
    fFieldCount: integer;
    fFieldNames: array of PChar;
    fFieldSizes: array of longword;
    fFieldOffsets: array of longword;
    fFieldTypes: HidtArray;

TTableDescriptor = class(TBaseCompoundDescriptor)
...
...

constructor TTableDescriptor.create;
begin
  inherited create;
  GetMem(fInfo, sizeof(TTableInfo));
...
function TTableDescriptor.GetInfo: PTableInfo;
begin
  with fInfo^ do begin
    Name := fItemName;
    TotalSize := fTotalTypeSize;
    ElementNames := fFieldNames;

the last line trying to assign a (already sized and holding information) dynamic array to a similar variable fails:

Program received signal SIGSEGV, Segmentation fault. 0x8051eb5 in fpc_dynarray_decr_ref ()
(gdb) bt
#0 0x8051eb5 in fpc_dynarray_decr_ref ()
#1 0x80a2b26 in TTABLEDESCRIPTOR__GETINFO (this=0x283981e8) at CompoundTypes.pas:398 #2 0x80624e3 in TDS_HDF__INIT (C=0x80a8fc4, this=0x283c8028) at DS_HDF.pp:210 #3 0x8064fd1 in TDATACONVERTER__CONVERT (this=0x283b0248) at DataConverter.pp:191 #4 0x8049425 in main () at DC.pas:156

The ref guide says when assigning one dyn-array to another variable of the same type, this is done by reference and those arrays are ref-counted.

Why does it fail?

I tried using SetLength on the target var first, same error.

TIA,
Marc

Reply by email

Jonas Maebe
to Marc Santhoff
Marc Santhoff wrote
constructor TTableDescriptor.create; begin inherited create; GetMem(fInfo, sizeof(TTableInfo));

Getmem allocates memory, but does not perform any initialisation. Use new() for record types containing fields that must be initialised (such as all reference counted types).

Joans

Reply by email

Marc Santhoff
to Jonas Maebe
Jonas Maebe wrote 10 lines
On 12 Nov 2008, at 21:53, Marc Santhoff wrote: > constructor TTableDescriptor.create; > begin > inherited create; > GetMem(fInfo, sizeof(TTableInfo)); Getmem allocates memory, but does not perform any initialisation. Use new() for record types containing fields that must be initialised (such as all reference counted types).

That does work. :)

So the caller has to use Dispose() instead of FreeMem() or will the work the same?

Thanks,
Marc

Reply by email

Jonas Maebe
to Marc Santhoff
Marc Santhoff wrote 13 lines
Am Mittwoch, den 12.11.2008, 22:30 +0100 schrieb Jonas Maebe: > On 12 Nov 2008, at 21:53, Marc Santhoff wrote: > > > Getmem allocates memory, but does not perform any initialisation. Use > new() for record types containing fields that must be initialised > (such as all reference counted types). That does work. :) So the caller has to use Dispose() instead of FreeMem() or will the work the same?

It's the same deal: freemem frees record's memory but does not finalise its contents, so you get memory leaks. Use dispose.

Jonas

Reply by email