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