yesterday I had some memory corruption going on and I'm highly suspect of how some record arrays are being allocated and deallocated. This is the short version for demostration:
type
TMyRecord = record
W: word;
S: String;
end;
TMyRecordArray = array [1 .. 315] of TMyRecord;
TArrayPointer = ^TMyRecordArray;
var
PageBase: TArrayPointer;
procedure TTestForm.FormCreate(Sender: TObject);
var
iRecord: TMyRecord;
begin
PageBase := AllocMem(SizeOf(TMyRecordArray));
iRecord.W := 1;
iRecord.S := 'TEST';
PageBase^[1] := iRecord;
end;
procedure TTestForm.FormDestroy(Sender: TObject);
begin
PageBase^[1] := Default (TMyRecord);
FreeMem(TPageBase);
end;
I'm fairly sure that I'm not doing this right, any suggestions would be appreciated.
The first thing to say is that the code you present works. It finalizes and deallocate correctly without leaking. So I'll try to answer your question more generally.
Strings are managed types and the compiler needs to use special memory allocation routines to be able to manage them: New and Dispose.
Allocate with
New(PageBase);
And deallocate with:
Dispose(PageBase);
The call to New ensures that any members that are managed are default initialized. And in the other direction, Dispose will finalize any managed members.
You could do this manually as your code attempts. But in the real code you would need to finalize every element of the array. Your code only finalizes one. Of course, it also initializes only one and as written in the question it is fine. Perhaps your short version for the question has simplified so far that the fault has been removed.
However, I am certainly not recommending that you deal with the managed types manually. Use New and Dispose for that.
It's also worth saying that a dynamic array would be much simpler here. Using a dynamic array would let the compiler take care of all the allocation and deallocation, and handle any managed types correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With