Managed types vs. GetMem

I’ve just seen the following question on StackOverflow:

I am getting an unexpected AV in the following code:

program Project65;


{$R *.res}


  ITest = interface

  TTest = class(TInterfacedObject, ITest)

  p: ^ITest;

  GetMem(p, SizeOf(ITest)); 
  p^ := TTest.Create; // AV here
    p^ := nil;

Now interestingly if I change the first line to

GetMem(p, 21);

than the AV is gone. (20 bytes or less fails). What is the explanation to this?

Simple: GetMem, as stated by the documentation, does not initialise the memory it allocates to zero. The chances are, therefore, that p^ is not nil when it comes to be assigned to the new instance of TTest; if that is the case however, then the low-level RTL will assume it points to a valid interface reference, and call _Release accordingly. As it in fact points to random bytes, an AV results. Importantly, the fact it does appear to be zero-initialised for the questioner if 21 not 4 bytes are requested is irrelevant: not ensuring memory is zero-initialised does not imply ensuring memory isn’t zero-initialised.

Moral of the story? If you mix and match relatively high level features (managed types) with relatively low level ones (dynamically allocating raw memory blocks), don’t be surprised if you need to perform bookkeeping for the former that is normally done for you.

Now in this particular case, using AllocMem instead of GetMem would be a quick fix. Nonetheless, I would personally advise not mixing and matching higher and lower level language features like this, unless there’s a good framework-y reason to do so. If you want to use pointers, just use pointers!

[Update: in between me writing this and it coming up on, two perfectly serviceable answers appeared on StackOverflow – check them out.]


One thought on “Managed types vs. GetMem

  1. Pingback: Delphi GetMem / FreeMem - New / Dispose - Seite 2 - Delphi-PRAXiS

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s