c++ - Delphi 中的动态数组和内存管理

标签 c++ arrays delphi pointers

下面关于 Delphi 中的动态数组的文章说您使用 SetLength() 函数分配一个动态数组。

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

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

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

问题是,如果SetLength()等同于C++的MyObject *obs = new MyObject[20],那么数组只是指针,因此将 Delphi myObjects 变量设置为 nil 是否与在 C++ 中设置 obj = NULL 相同?即,这是内存泄漏吗?

编辑:我从 David 的回答中了解到,编译器管理动态分配数组的内存。我也从他的回答中了解到编译器确实为普通类实例管理内存(因此使用 myObj := MyObject.CreatemyObj.Free, myObj := nil 等)。此外,因为 Delphi 类(不是记录)总是在堆上分配(Delphi 使用一种引用/指针系统),这是否意味着(自动内存管理的)动态数组中的所有对象仍然需要内存 -由我管理?例如,以下是否会通过双重释放结果导致错误?

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;

最佳答案

动态数组由编译器管理。这是通过维护对数组的所有引用的引用计数来完成的。当对数组的最后一个引用被分离时,数组被释放。

documentation说:

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.

在您的示例中,将 nil 分配给您的变量会分离唯一的引用并导致数组被释放。所以没有泄漏。

Delphi 动态数组与 C++ new 有很大不同。与 Delphi 中最接近的类似物是使用 GetMemNew 进行原始内存分配。


您的编辑提出了不同的问题。类的实例不受管理。必须明确释放它们。你的代码就是这样做的。没有双重释放,因为编译器不管理类的实例。

关于c++ - Delphi 中的动态数组和内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22085889/

相关文章:

android - 德尔福10 : Problems with SizeOf(string) - Windows vs Android

c++ - 在函数 C++14 中包含 STL 头文件

c++运算符重载的多态性

c++ - 转换问题

android - 如何将可变数量的参数传递给数据绑定(bind)适配器?

c++ - 如何将 "linearize"变成树形结构?

php - 将标准对象数组从 SOAP 循环到数据库 PHP

delphi - 跨进程单例对象

delphi - 交换字变量的字节(低/高)的过程

c++ - 从类节点上的结构中创建二叉搜索树会很糟糕吗?