dynamic arrays behaving funny

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

dynamic arrays behaving funny

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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: dynamic arrays behaving funny

Jonas Maebe-2

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).


Joans
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: dynamic arrays behaving funny

Marc Santhoff
Am Mittwoch, den 12.11.2008, 22:30 +0100 schrieb Jonas Maebe:

> 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: dynamic arrays behaving funny

Jonas Maebe-2

On 12 Nov 2008, at 22:46, Marc Santhoff wrote:

> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal