Dynamic arrays and memory management in Delphi

The next article on dynamic arrays in Delphi says that you allocate a dynamic array using the SetLength() function.

 myObjects : array of MyObject; ... SetLength(myObjects, 20); // Do something with the array. myObjects := nil; 

http://delphi.about.com/od/beginners/a/arrays.htm

This seems like a memory leak for me:

The question is , if SetLength() is the C ++ equivalent of MyObject *obs = new MyObject[20] , then the arrays are just pointers, so the Delphi parameter myObjects sets the value nil to the same as setting obj = NULL in C ++? Ie, is this a memory leak?

EDIT : I understand that David answers that the compiler manages memory for dynamically allocated arrays. I also understand from his answer how the compiler manages memory for regular class instances (hence using myObj := MyObject.Create and myObj.Free , myObj := nil , etc.). In addition, since Delphi classes (not records) are always allocated on the heap (Delphi uses a type of reference / pointer system), does this mean that all objects in a dynamic array (with automatic memory management) should still be associated with memory managed me? For example, does the cause cause a double release of the result?

 myObjects : array of MyObject; ... SetLength(myObjects, 20); for i := 0 to 19 do begin myObjects[i] := MyObject.Create; end; // Do something with the array. // Before de-allocating it, if I *know* I am the only user of the array, // I have to make sure I deallocate each object. for i := 0 to 19 do begin myObjects[i].Free; myObjects[i] := nil; // Redundant, but for illustrative purposes. end; myObjects := nil; 
+3
source share
2 answers

Dynamic arrays are controlled by the compiler. This is done by maintaining the reference number of all array references. When the last array reference is disabled, the array is freed.

The documentation says:

Dynamic array variables are implicit pointers and are controlled by the same reference counting method used for long strings. To free a dynamic array, assign nil to a variable that references the array or passes the variable to Finalize; any of these methods provides an array if there are no other references to it. Dynamic arrays are automatically freed when their reference count drops to zero. Dynamic arrays of length 0 are nil. Do not apply the dereference operator (^) to a dynamic array variable or pass it to the New or Dispose procedure.

In your example, assigning nil your variable separates the one and only reference and frees the array. So there is no leak.

Delphi dynamic arrays are very different from C ++ new . The closest counterpart in Delphi is raw memory allocation using GetMem or new .


Your assignment asks another question. Class instances are not managed. They must be explicitly released. Your code does this. There is no double access because the compiler does not manage class instances.

+4
source

Setting the object reference to nil DOES NOT free it. It simply decreases the internal reference count. When this reference counter reaches 0, the memory is freed or available for free.

So:

 Obj.Free Obj := nil; 

not going to release him twice. He is going to free it once and set the pointer Obj to null.

For strings, a reference counter was used to store an offset of 2 words before the first element, and the size was saved by 1 word before the first element. If it is constant, the reference count is usually -1. Not sure if this is still the case.

-1
source

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


All Articles