Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
512 views
in Technique[技术] by (71.8m points)

c++ - Dynamic arrays and memory management in Delphi

The following 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 to me:

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

EDIT: I understand from David's answer that the compiler manages memory for dynamically allocated arrays. I also understand from his answer than the compiler does manage memory for ordinary class instances (hence the use of myObj := MyObject.Create and myObj.Free, myObj := nil, etc). Also, because Delphi classes (not records) are always allocated on the heap (Delphi using a kind of reference/pointer system), does that mean that all the objects within the (automatic memory-managed) dynamic array still need to be memory-managed by me? E.g., does the following cause a fault by double freeing a 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;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Dynamic arrays are managed by the compiler. This is done by maintaining a reference count of all references to the array. When the last reference to the array is detached, the array is deallocated.

The documentation says:

Dynamic-array variables are implicitly pointers and are managed by the same reference-counting technique used for long strings. To deallocate a dynamic array, assign nil to a variable that references the array or pass the variable to Finalize; either of these methods disposes of the array, provided there are no other references to it. Dynamic arrays are automatically released when their reference-count drops to zero. Dynamic arrays of length 0 have the value 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 to your variable detaches the one and only reference and results in the array being deallocated. So there is no leak.

Delphi dynamic arrays are very different from C++ new. The closest analogue to that in Delphi is raw memory allocation with GetMem or New.


Your edit asks a different question. Instances of classes are not managed. They must be explicitly be freed. Your code does that. There is no double free because the compiler does not manage instances of classes.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...