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@delphi.org.nz
>>> Admin: http://delphi.org.nz/mailman/listinfo/delphi
>>> Unsubscribe: send an email to delphi-requ...@delphi.org.nz with
>>> Subject: unsubscribe
>>>
>>
>
>
> _______________________________________________
> NZ Borland Developers Group - Delphi mailing list
> Post: delphi@delphi.org.nz
> Admin: http://delphi.org.nz/mailman/listinfo/delphi
> Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
> unsubscribe
>

_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe

Reply via email to