Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctly allocating/freeing memory for records in static array

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.

like image 555
Walter78 Avatar asked Feb 02 '26 20:02

Walter78


1 Answers

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.

like image 74
David Heffernan Avatar answered Feb 05 '26 13:02

David Heffernan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!