[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