[DUG] [computing] Sizeof record gives error
David Moorhouse
delphi at moorhouse.net.nz
Fri Aug 26 01:49:40 NZST 2011
Hi Peter
Been there done that :)
The function call is fine. It is the assignment that causes the AV -
because the "bucket" is too small.
Assigning it with 16 bytes fixes the problem, regardless of how many
items the array holds.
I smell compiler magic in the background.
Cheers
D
On 25/08/11 17:29, Peter Ingham wrote:
> Another attempt to reply...
>
> First thing to do is determine if the crash occurs in the procedure call,
> on the subsequent assign, or in between.
>
> Give this a try:
> procedure TUserClass.Log(const LogType: TLogType; const Args: array of
> const );
> var
> LogData: PLogData;
> TempArgs : TConstArray;
> begin
> // size of record TLogData does not work
> GetMem(LogData, sizeof(TLogData));
> LogData.LogType := LogType;
> // blows up on one of these lines
> TempArgs := CreateConstArray(Args);
> LogData.LogArgs := TempArgs;
> // ... do some other stuff with the LogData item finally calling
> FreeMem
> end;
>
>
> Regarding the size of a dynamic array, like a string variable, the
> variable (LogArgs in this case) is the size of a pointer (i.e. 4 bytes
> for Win32). If the pointer is non-zero, it points to a structure which
> includes the adjacent array elements preceded by a length.
>
> One thing to watch out for is that Getmem does not clear the allocated
> memory, so LogData after the Getmem call will contain any old rubbish.
> The reference to LogData.LogArgs in the assignment may be
> dereferencing a non-zero pointer & attempting to use whatever it
> contains.
>
> Cheers
>
>
> On 25/08/2011 11:40 a.m., David Moorhouse (DUG) wrote:
>> I have the following code snippet
>>
>> <code>
>> type
>> PConstArray = ^TConstArray;
>> TConstArray = array of TVarRec;
>>
>> function CreateConstArray(const Elements: array of const): TConstArray;
>>
>> type
>> TLogType = (ltError, ltWarn, ltInfo);
>> PLogData = ^TLogData;
>> TLogData = record
>> LogType: TLogType;
>> LogArgs: TConstArray;
>> end;
>>
>> ....
>>
>> procedure TUserClass.Log(const LogType: TLogType; const Args: array of
>> const );
>> var
>> LogData: PLogData;
>> begin
>> // size of record TLogData does not work
>> GetMem(LogData, sizeof(TLogData));
>> LogData.LogType := LogType;
>> // blows up on next line
>> LogData.LogArgs := CreateConstArray(Args);
>> // ... do some other stuff with the LogData item finally calling
>> FreeMem
>> end;
>>
>> function CreateConstArray(const Elements: array of const): TConstArray;
>> var
>> I: Integer;
>> begin
>> SetLength(Result, Length(Elements));
>> for I := Low(Elements) to High(Elements) do
>> Result[I] := // assign a TVarRec here
>> end;
>> </code>
>>
>> The code that assigns the memory only assigns 8 bytes - and an access
>> violation ensues. If I replace the call to "sizeof" with the number 16,
>> the code works fine.
>>
>> My understanding of dynamic arrays was that the compiler created a 4
>> byte
>> field before the first element that contained the length of the array.
>>
>> So why does the sizeof function not reflect this ? And why do I
>> need 16
>> bytes not 12 (4 for LogType + 4 for length of array + 4 for array
>> pointer)?
>> Also regardless of the number of items in the open array parameter, 16
>> bytes works, so it does not relate the length of the TConstArray.
>>
>> Your thoughts ?
>>
>> David
>>
>>
>>
>> _______________________________________________
>> NZ Borland Developers Group - Delphi mailing list
>> Post: delphi at delphi.org.nz
>> Admin: http://delphi.org.nz/mailman/listinfo/delphi
>> Unsubscribe: send an email to delphi-request at delphi.org.nz with
>> Subject: unsubscribe
>>
>
More information about the Delphi
mailing list