[DUG] [computing] Sizeof record gives error
Peter Ingham
ping_delphilist at 3days.co.nz
Fri Aug 26 08:17:08 NZST 2011
Try filling LogData with binary zeros after the Getmem & before the assign.
FillChar (LogData^, sizeof(TLogData), 0);
I believe the uninitialized memory is messing up the compiler magic
associated with the dynamic array.
Any reason the local Tlogdata record is referenced via a pointer?
I suspect the following will also work:
procedure TUserClass.Log(const LogType: TLogType; const Args: array of
const );
var
LogData: TLogData;
begin
LogData.LogType := LogType;
LogData.LogArgs := CreateConstArray(Args);
// ... do some other stuff with the LogData item finally calling
end;
Cheers
On 26/08/2011 1:49 a.m., David Moorhouse wrote:
> 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
>>>
>>
>
>
> _______________________________________________
> 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