Search code examples
multithreadingdelphimemoryvcl

Delphi pointer memory and freeing


I'm using custom windows messages to exchange information from the worker thread to the forms in the main VCL thread. Whenever I need to send some data with the message I do this:

type
  PntStr = ^string;

then PostMessage()

var
    pointString : PntStr;

(...)

New(pointString);
pointString^ := mystring;
PostMessage(frmDest.Handle, UM_THREADMSG, UM_MYEVENT1, LPARAM(pointString));

On the receiving form

try
  myStrP := PntStr(MSG.LParam);
  myfunction(myStrP^);
finally
  Dispose(myStrP);
end;

Is this the correct way to deal with the memory allocated by the pointer? Does calling Dispose() on the pointer take care of freeing the memory?


Solution

  • Yes, your approach is correct in terms of memory management. New and Dispose correctly deal with the managed type. That's really what they exist to do.

    Some nuances:

    • Check the return value of PostMessage. If it fails then the message was not posted and the thread needs to dispose of the memory.
    • Don't use a form's handle as the recipient. There is a race condition. The form's window may be recreated simultaneously with you posting the message. Then the message will be lost. Or worse delivered to a different window if the handle is re-used. Or worse still, the window could be re-created on the wrong thread. Instead use AllocateHWnd to create a window handle whose life you control.
    • Your try/finally is wrong. The try should appear after the resource has been acquired. This is one of the most common mistakes we see here. In your code it is likely benign because the assignment cannot raise an exception but it is still worth being accurate.