Delphi Memory Management

I was not able to find answers to several questions on memory management Delphi. I could test different scenarios (what I did to find out what the FreeAndNil method violates), but it takes too much time and its hard! But seriously, I would also like to know how all of you (Delphi developers) deal with these memory management issues.

My questions (Feel free to create your own, I'm sure the answers to them will help me too):

  • Does FreeAndNil work for COM objects? My thoughts are that I don’t need this, but if all I have to do is set it to zero, why not stay consistent in my finally block and use FreeAndNil for everything?

  • What is the correct way to clear static arrays (myArr: Array [0..5] TObject). I can’t FreeAndNil, so is it enough just to set it to zero (do I need to do this after I have FreeAnNil'd for each object?)?

Thanks guys!

+4
source share
4 answers

COM objects are referenced through interfaces that you do not need to do for free. The compiler will take care of the necessary logic for counting links to make sure that the COM object will be deleted at the right time.

As for static arrays (or dynamic arrays, for that matter), they also should not be freed by you. If they contain objects, then the objects should be freed at the appropriate time, but arrays do not.

Also, never use FreeAndNil for anything that is not an object reference. Using it with interfaces or other variables can lead to memory corruption. It's best to never use it (use Free instead) if you are not dealing with an object that you need to free, and then reuse later.

+8
source

First, in most cases, FreeAndNil is a bit overkill. This is convenient when you free an object field outside its destructor or a global (ugly) variable. But most of the time, just calling is enough.

As you know, an object variable is actually a pointer to the data of the object. When you call Free, this buffer is freed (after the destructor starts, of course), but the Object variable still points to the newly freed memory position. It was called the Hanging Pointer. Having a sagging pointer is not a problem as long as you KNOW that it dangles in this context. For instance:

Procedure Myproc; var vString : TStringList; begin //Here, vString is "dangling" vString := TStringList.Create; //Here, vString is valid try //Do some stuff finally vString.Free; end; //Here, vString is "dangling"... But who care, it about to go out of scope and we won't use it again. end; 

Calling FreeAndNil makes more sense in a global variable, where you don't know exactly when and how to free a variable. With that said, there is nothing wrong with calling FreeAndNil all the time (except for very tight loops where you try to get every ounce of performance).

Now, for COM objects ... As Mason said, they are counted. Therefore, if you keep a single reference to this interface, a call to MyInterface := nil; set him free. But when / if the variable goes out of scope, the compiler will take care of adding the cleanup code to make sure that the link to the interface is reduced. Therefore, if you are trying to keep the memory requirement to a minimum, set the interface to nil. Otherwise, it does not really matter.

As for your array ... You can just call Free on all the items in the list ... Optionally set them to zero after.

+2
source

As for static arrays, if you created the contents of an array, just free the objects you created. You do not need to do anything to clear the space used by myArr itself.

+1
source

COM objects are automatically counted; as soon as a variable goes out of scope or an object that has an interface pointer when deleting a field, Delphi will call _Release and the object will delete itself. You do not need to explicitly set the value to nil.

For static arrays you need to iterate over them and free each object for free.

+1
source

Source: https://habr.com/ru/post/1305036/


All Articles