如何在Delphi中正确释放包含各种类型的记录? [英] How to properly free records that contain various types in Delphi at once?

查看:371
本文介绍了如何在Delphi中正确释放包含各种类型的记录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  type 
TSomeRecord = Record
field1:integer;
field2:string;
field3:boolean;
结束;
var
SomeRecord:TSomeRecord;
SomeRecAr:数组的TSomeRecord;

这是我所拥有的最基本的例子,因为我想重用 SomeRecord (某些字段保持为空,并且在我重新使用 SomeRecord 之前,不会释放所有的字段,这显然是不需要的)我正在寻找一种方式来一次释放所有的领域。我已经开始使用 string [255] ,并使用 ZeroMemory(),这是很好,直到它开始泄漏内存,那是因为我切换到 string 。我仍然缺乏了解为什么的知识,但它似乎与动态有关。我也使用动态数组,所以我假设在任何动态的情况下尝试 ZeroMemory()会导致泄漏。有一天浪费了。我想我通过使用 Finalize() SomeRecord SomeRecAr before ZeroMemory(),但我不知道这是正确的方法还是只是我是愚蠢的。


$ b $所以问题是:如何一次释放所有东西?有没有一些单一的程序存在,我不知道?



另一方面,我可以建议如何不同地实现这些记录开始,所以我不需要做复杂的尝试释放的东西。我已经研究了用 New()创建记录,然后摆脱它 Dispose(),但我有当调用 Dispose()之后的变量是未定义的,而不是nil,这意味着什么。另外,我不知道某种类型的变量( SomeRecord:TSomeRecord )与指向类型的变量( SomeRecord:^ TSomeRecord )。我正在研究上述问题,除非有人可以快速解释,否则可能需要一些时间。

解决方案

假设您有一个支持在记录上实现方法的Delphi版本,您可以清除以下记录:

 键入
TSomeRecord = record
field1:integer;
field2:string;
field3:boolean;
程序清除;
结束

程序TSomeRecord.Clear;
begin
自我:=默认(TSomeRecord);
结束

如果您的编译器不支持默认那么你可以这样做:

  procedure TSomeRecord.Clear; 
const
默认值:TSomeRecord =();
begin
自我:=默认;
结束






您可能希望避免将值类型突变一个方法。在这种情况下,创建一个返回空记录值的函数,并使用赋值运算符:

 键入
TSomeRecord = record
// fields go here
class function Empty:TSomeRecord;静态的;
结束

类函数TSomeRecord.Empty:TSomeRecord;
begin
结果:=默认值(TSomeRecord);
结束

....

值:= TSomeRecord.Empty;






除此之外,我找不到任何文档参考对于 Default(TypeIdentifier)。有谁知道在哪里可以找到?






至于你的问题的第二部分,我看不出没有理由不继续使用记录,并使用动态数组进行分配。尝试自己管理一生的时间更容易出错。


type
  TSomeRecord = Record
    field1: integer;
    field2: string;
    field3: boolean;
  End;
var
  SomeRecord: TSomeRecord;
  SomeRecAr: array of TSomeRecord;

This is the most basic example of what I have and since I want to reuse SomeRecord (with certain fields remaining empty, without freeing everything some fields would be carried over when I'm reusing SomeRecord, which is obviously undesired) I am looking for a way to free all of the fields at once. I've started out with string[255] and used ZeroMemory(), which was fine until it started leaking memory, that was because I switched to string. I still lack the knowledge to get why, but it appears to be related to it being dynamic. I am using dynamic arrays as well, so I assume that trying ZeroMemory() on anything dynamic would result in leaks. One day wasted figuring that out. I think I solved this by using Finalize() on SomeRecord or SomeRecAr before ZeroMemory(), but I'm not sure if this is the proper approach or just me being stupid.

So the question is: how to free everything at once? does some single procedure exist at all for this that I'm not aware of?

On a different note, alternatively I would be open to suggestions how to implement these records differently to begin with, so I don't need to make complicated attempts at freeing stuff. I've looked into creating records with New() and then getting rid of it Dispose(), but I have no idea what it means when a variable after a call to Dispose() is undefined, instead of nil. In addition, I don't know what's the difference between a variable of a certain type (SomeRecord: TSomeRecord) versus a variable pointing to a type (SomeRecord: ^TSomeRecord). I'm looking into the above issues at the moment, unless someone can explain it quickly, it might take some time.

解决方案

Assuming you have a Delphi version that supports implementing methods on a record, you could clear a record like this:

type
  TSomeRecord = record
    field1: integer;
    field2: string;
    field3: boolean;
    procedure Clear;
  end;

procedure TSomeRecord.Clear;
begin
  Self := Default(TSomeRecord);
end;

If your compiler doesn't support Default then you can do the same quite simply like this:

procedure TSomeRecord.Clear;
const
  Default: TSomeRecord=();
begin
  Self := Default;
end;


You might prefer to avoid mutating a value type in a method. In which case create a function that returns an empty record value, and use it with the assignment operator:

type
  TSomeRecord = record
    // fields go here
    class function Empty: TSomeRecord; static;
  end;

class function TSomeRecord.Empty: TSomeRecord;
begin
  Result := Default(TSomeRecord);
end;

....

Value := TSomeRecord.Empty;


As an aside, I cannot find any documentation reference for Default(TypeIdentifier). Does anyone know where it can be found?


As for the second part of your question, I see no reason not to continue using records, and allocating them using dynamic arrays. Attempting to manage the lifetime yourself is much more error prone.

这篇关于如何在Delphi中正确释放包含各种类型的记录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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