0

Is there a way to check if a pointer has been already disposed?

  TRecTest = record
    Test : string;
  end;
  PRecTest = ^TRecTest;

...

var
  P : PRecTest;
begin
  New(P);
  //...
  Dispose(P);

  //here I want to check that P has been already disposed
end;

If I call Dipose(P) again, an EInvalidPointer exception with message 'Invalid pointer operation' is raised.

I know I could set it to nil and then use Assigned...

var
  P : PRecTest;
begin
  New(P);
  //...
  Dispose(P);
  P := nil;

  if(not Assigned(P))
  then ShowMessage('Disposed');
end;

...but I would like to know if it's possible to check if P is still a valid pointer without setting its value to nil.

Fabrizio
  • 7,603
  • 6
  • 44
  • 104
  • No, it is not possible. Setting the pointer to nil after disposing the memory is the only viable option, if you intend to check the same pointer at a later time. But if you have multiple pointers to the same memory, and you dispose the memory via one of the pointers, all bets are off, unless you have a mechanism in place to nil out all of the pointers. – Remy Lebeau Apr 11 '18 at 16:03
  • 1
    @Remy, if that was not possible, how would the memory manager knew that the data pointed by the pointer were already released (in order to raise the invalid pointer operation exception)? – Victoria Apr 11 '18 at 16:19
  • 3
    @Victoria The memory manager knows the memory blocks it allocates. There is no (standard) way to query the memory manager if a given address is still allocated. And the memory manager is not the one raising the `EInvalidPointer` exception, the OS is, which the RTL translates into `EInvalidPointer`. But that is not a guarantee, if the memory manager caches disposed memory for reuse, then a disposed memory block is not "invalid" from the OS's perspective, so accessing the contents of the memory might not crash at all. It is *undefined behavior* to access disposed memory, *anything* could happen. – Remy Lebeau Apr 11 '18 at 16:20
  • @Remy, I've noticed that memory manager sets the `IsFreeBlockFlag` flag in the block header when you perform dispose, so couldn't [this be of help](https://pastebin.com/RZPSNgc8) (or maybe [this](https://pastebin.com/WApYB2Kh))? – Victoria Apr 11 '18 at 16:39
  • @Victoria Like I said earlier, there is no *standard* way to query the memory manager for a memory block's disposed status. What you describe is an **implementation detail** of a *specific* memory manager (FastMM). Remember that Delphi allows you to swap out the memory manger for any implementation you want. And besides, FastMM caches and reuses "freed" memory, so after a memory block is disposed, it could get un-disposed and re-purposed at a later time, so your `IsDisposed()` function wouldn't be able to tell you if a memory block got reused for something else. – Remy Lebeau Apr 11 '18 at 16:51
  • 1
    As others have said: you can't. If you think you need something like it, you have problems managing memory. Read [Dalija Prasnikar's book about memory management](https://dalija.prasnikar.info/delphimm/) or first (a little shorter): [my article about Pointers](http://rvelthuis.de/articles/articles-pointers.html#badpointers). – Rudy Velthuis Apr 11 '18 at 17:56
  • @Victoria: of course a memory manager has knowledge about its own internal details. We, as users, generally don't have such knowledge. – Rudy Velthuis Apr 11 '18 at 17:59
  • @RudyVelthuis The memory manager doesn't even have this information because of re-use. – David Heffernan Apr 11 '18 at 19:47
  • @David I think dthorpe's answer on my linked dupe question covers such info quite nicely, and especially valuable considering who he is. However, I accepted the other answer because it was straight forward and to the point. – Jerry Dodge Apr 11 '18 at 19:56
  • @David, memory manager should keep the information about whether certain block is free or not of course. The problem is when a block of memory is used by a different structure (which is what you and Remy were trying to point at). Otherwise code linked by me would be sufficient for FastMM shipped with Delphi Tokyo. – Victoria Apr 11 '18 at 23:25
  • @Jerry: Danny Thorpe was at Borland when there was only one, Borland-made memory manager in use, and that was **not** FastMM. So while he may have had intimate knowledge of the memory manager of those days, nowadays, we use a different one. And even then, it was pluggable, although that was not a very common thing to do. – Rudy Velthuis Apr 12 '18 at 13:48
  • @David: of course the memory manager can't tell if a memory slot is re-used and if a pointer is still valid, but what I meant is that it keeps track of its own internals (only). – Rudy Velthuis Apr 12 '18 at 13:52

0 Answers0