【发布时间】:2014-05-05 06:55:58
【问题描述】:
我正在努力摆脱短字符串。 目前在我们的程序中使用短字符串的许多地方之一是在记录中。 很多这些记录都保存在 AVL 树中。
使用的 AVL 树是一个通用的树,包含一个指向多个字节 (ElemSize) 的指针,到目前为止运行良好。
AVL 树中每条记录的内存使用GetMem 分配,并使用Move 进行复制。
但是,由于字符串是指向引用计数结构的指针,因此将内存复制回记录不再起作用,因为引用的字符串通常被释放(通过引用计数自动释放)。
只有一个指针和“数据块”的大小,我认为不可能增加字符串的引用计数。
我正在寻找一种方法来获取在将记录存储在 AVL 树中时要考虑的字符串的引用计数。
我可以将记录类型传递给树构造函数,然后将指针转换为这种类型,从而增加引用吗?或类似的修复,我可以将更改隔离为主要在 AVL 单元中并调用它的构造函数。
用于分配空间以存储 AVL 中记录的当前代码; XData 是指向要存储的记录的指针:
New(RootPtr); { create new memory space }
GetMem(RootPtr^.TreeData, ElemSize);
WITH RootPtr^ DO BEGIN
{ copy data }
Move(XData^, RootPtr^.TreeData^, ElemSize);
【问题讨论】:
-
实际上您需要进行适当的重新设计。你不能这样继续下去。
-
为什么需要担心引用计数?当然,您在树节点中的记录将包含一个自动引用的
string,最好的方法是摆脱为您的记录(例如New、GetMem)手动分配内存并使用新方法。我会让节点亲自存储对象引用。它可能比你目前正在做的内存移动更有效率。 -
@DavidM 1. 目前,树节点中没有记录,只有一个指针
TreeData(它包含记录数据,但未声明为记录)。 2. 从树中取出的记录通常用于临时计算,这不应该反映在正确的记录中,因此我们需要在每次请求时将记录复制出来,而不是传递引用。 -
@DavidHeffernan 重新设计如何摆脱 AVL?还是远离记录?当我们的程序准备好超越 Delphi 2007 时,我希望切换到通用容器类。但现在还没有,而且随着升级的时间,我必须在很多旧代码之间优先考虑,试图超越 2007。
-
@MGH 我添加了一个答案,其中概述了我认为最简单的方法,让您在没有太多变化的情况下继续前进
标签: delphi record delphi-2007 reference-counting