views:

113

answers:

2

I have been running into errors where objects are somehow freed but we end up calling FreeMem on them. Of course this causes an error since the memory has already been freed and throws an error.

I know that a try-catch block would probably fix it but that's a lot of try-catch blocks. With the regular object.free the way to avoid this is FreeAndNil(object) but I can't find the equivalent for FreeMem. Something which tests whether it's allocated or not before freeing.

What's the best solution here in ease of reading, maintainability, and stability.

+8  A: 

The equivalent to FreeAndNil would just be

FreeMem(p);
p := nil;

But you'll better fix the real problem by finding which object you use after it's freed. Try FastMM - it will help you with that task.

Ulrich Gerhardt
Thanks for the advice. I tracked down the issue and it is that durring the creation of an object I run out of memory. This throws an error and control returns to the block which called the create on the object. The problem is that the create is in a try-catch block with a finally section which frees the object. In the destroy for that object it calls FreeMem(p) so it turns out that the memory was never allocated in the first place. I can probably fix this by initalizing all p to nil.
Daisetsu
The part of code that allocates the resource should never be inside the ` try-finally ` block, it should be immediately before the ` try `. If there are valid reasons to have the AllocMem within the ` try-finally ` block that ends up calling FreeMem in ` finally ` then assign the pointer `nil` before you enter the `try` to make the `finally` safe.
Cosmin Prund
freemem is already VAR, so you could simply implement this in the memory manager. The reason that freeandnil exists is that you don't have a reference to the place where the object reference is stored when you do .Free; You only have the value (the object)
Marco van de Voort
A: 

You shouldn't be calling FreeMem on an object anyway. It needs to be destroyed with its destructor, by calling Free on it. But if you're working with pointers to other things (records, for example,) then go with what Ulrich said. (Both parts of it.)

Mason Wheeler
Actually Daisetsu needs to stop calling memory obtained from AllocMem an Object.
Cosmin Prund
@Cosmin: The word "object" isn't necessarily that narrowly defined.
Ulrich Gerhardt
As an example of Ulrich: TP objects (that Delphi still supports) can be perfectly fine allocated with allocmem. And Classes have instancesize for a reason.
Marco van de Voort