动态数组和内存管理在Delphi [英] Dynamic arrays and memory management in Delphi

查看:300
本文介绍了动态数组和内存管理在Delphi的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是在Delphi动态数组下面的文章说,您分配使用 SetLength函数()功能的动态数组。

  myObjects:MyObject的数组;
...
SetLength函数(myObjects,20);
//使用数组的东西。
myObjects:=零;

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

这似乎是内存泄漏对我说:

现在的问题是,如果 SetLength函数()是C ++ 为MyObject *观测值=新MyObject来[相当于20] ,则数组只是指针,所以是设置德尔福 myObjects 变量在C相同的设置 OBJ = NULL ++?即,这是一个内存泄漏?

修改:我从大卫的回答明白,编译器负责管理动态分配的内存阵列。我也从他的回答了解比编译器管理的普通类实例存储(因此使用 MyObj中的:= MyObject.Create myObj.Free MyObj中:=零等)。同时,由于德尔福类(不记录)总是在堆上分配(德尔福使用一种参考/指针系统),这是否意味着(自动存储管理)动态数组中的所有对象仍需要内存 - 由我管理的?例如,双释放的结果执行以下操作导致故障?

  myObjects:MyObject的数组;
...
SetLength函数(myObjects,20);
对于i:= 0〜19做
开始
  myObjects [I]:= MyObject.Create;
结束;
//使用数组的东西。
//之前解除分配它,如果我知道* *我是数组的唯一用户,
//我要确保我释放每个对象。
对于i:= 0〜19做
开始
  myObjects [I]。自由;
  myObjects [I]:=零; //冗余,但为了说明的目的。
结束;
myObjects:=零;


解决方案

动态数组由编译器进行管理。这是通过保持到阵列的所有引用的参考计数进行。当对数组的最后一个引用被分离,阵列释放。

借助文档说:


  

动态数组变量是隐含的指针和由用于长字符串相同的参考计数技术来管理。要释放一个动态数组,分配到零引用数组或变量传递给最终确定变量;这些方法之一阵列的处置,提供有到它没有其它的引用。当他们的引用计数下降到零动态数组被自动释放。长度为0的动态数组有值为零。不要引用操作(^)适用于动态数组变量或将它传递给新的或处置过程。


在你的榜样,指派来您的变量分离被释放的人;仅作参考,数组中的结果。所以没有泄漏。

Delphi的动态数组从C ++ 很大的不同。最接近的模拟到,在德尔福原始内存分配与 GetMem函数


您的编辑问了一个不同的问题。类的实例不管理。它们必须被明确释放。您code做到这一点。不存在双重释放,因为编译器不管理类的实例。

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;

解决方案

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.

这篇关于动态数组和内存管理在Delphi的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆