【问题标题】:Understanding memory allocation for TList<RecordType>了解 TList<RecordType> 的内存分配
【发布时间】:2011-05-30 01:44:00
【问题描述】:

我必须存储可以在 Delphi 中轻松实现为记录的 TList(五个简单字段)。但是,我不清楚当我执行TList&lt;TMyRecordType&gt;.Add(R) 时会发生什么。

由于 R 是我创建 TList 的过程中的局部变量,我假设它的内存将在函数返回时被释放。这会在列表中留下无效的记录指针吗?还是列表知道分配时复制?如果是前者,我假设我必须使用 New() 和 Dispose() 手动管理 R 的内存,对吗?

或者,我可以通过简单地将字段声明为公共字段(甚至无需将它们设为正式属性)来将我的记录类型“提升”为类类型。这被认为可以吗,还是我应该花时间用私有字段和公共属性构建类?

【问题讨论】:

    标签: delphi memory-management delphi-2010


    【解决方案1】:

    简化:记录是数据块,默认情况下按值传递 - 即通过复制它们。 TList&lt;T&gt; 将值存储在 T 类型的数组中。因此,TList&lt;TMyRecordType&gt;.Add(R) 将值 R 复制到数组中的位置 Count 中,并将 Count 加一。无需担心内存的分配或释放。

    您通常不需要担心的更复杂的问题:如果您的记录包含字符串类型、接口类型、动态数组或本身包含这些类型之一的字段的记录,那么它是不仅仅是数据的简单副本;而是使用 System.pas 中的 CopyRecord,以确保正确更新引用计数。但是通常你不需要担心这个细节,除非你使用Move 来移动你周围的位,或者做类似的低级操作。

    【讨论】:

    • 关键是记录是值类型,类的实例是引用类型。确实需要了解其中的区别。
    • 您还可以将指针传递给记录类型...并拥有所有引用类型的好处。如果您的记录保存在内存中(在全局未触及列表或内存映射文件中),这是一种非常方便的方法。但这可能有点技术性,而不是 Delphi 的“标准”使用。用户应该更好地使用类,并且只有当它确实产生影响时才记录。
    • @David:是的,但是当列表本身被释放时,这些项目会自动删除吗?还是在释放列表之前我必须这样做?
    • @Larry 他们将被列表释放。真的,只是假装您使用的是 Integer 而不是 TMyRecordType。生命周期语义是相同的。
    • 啊哈!我缺少的概念是 TList 具有与 TList 不同的内存管理行为。谢谢你说清楚。
    猜你喜欢
    • 2019-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    • 2018-01-23
    相关资源
    最近更新 更多