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

Reply via email to