TDictionary中的内存泄漏 - 解决方法存在问题吗?

3

我正在考虑使用新的TDictionary类型。但是在QualityCentral上,我读到了两个由TDictionary引起的内存泄漏:

http://qc.codegear.com/wc/qcmain.aspx?d=67355

我刚刚实现了提出的解决方法,基本上是子类化TDictionary,重写析构函数并手动释放导致泄漏的两个对象:

destructor TMemCorrectedDictionary.Destroy;
begin
  Values.Free;
  Keys.Free;
  inherited;
end;

问题是,由于Values和Keys是TDictionary的只读属性,我无法将它们设置为nil。好吧,为了明确起见,现在一切都运行良好,但我想知道如果CodeGear发布一个修补程序来释放这两个对象并在它们自己的析构函数中再次释放它们,会发生什么。这不会导致访问冲突吗?
提前感谢您的阅读(和希望的回答)。

谢谢你的回答。虽然我不太喜欢依赖别人在释放对象后将所有对象设置为nil的想法。或许我有点多疑? - jpfollenius
我明白你的意思并且同意。如果我是你,我会在热修复或服务包中解决这个问题时再次查看源代码 - 只是为了确保。我希望修复能够很快到来,因为TDictionary中还有其他严重的错误需要紧急修复。 - Heinrich Ulbricht
请注意,目前应避免使用TDictionary,因为其Clear方法存在错误和其糟糕的Add性能。有关更多详细信息,请参见此处:http://alex.ciobanu.org/?p=59 - Mihai Limbășan
3个回答

2

我不知道Delphi的早期版本如何,但在XE5中有TObjectDictionary类来负责释放所有子项。


1
正如您在QC項目中所看到的,問題已在版本12.0.3299.19016中解決。這意味著Delphi 2009用戶應檢查其使用的版本(參見問題標籤),所有使用更新版本的用戶都應該沒有問題。 - sausagequeen

2
您可以先调用 inherited 方法并检查属性是否仍然被设置:
destructor TMemCorrectedDictionary.Destroy;
begin
  inherited;
  Values.Free;
  Keys.Free;
end;

顺便提一下: Free 方法不在乎要释放的实例是否为 nil,所以只有当 inherited Destroy 方法将属性设置为 nil 时,这个方法才能正常工作。

这是很危险的,因为继承的对象可能已经释放了你之后引用的内存。只使用 .Free 就可以了,因为它会自动检查是否为空。 - mj2008
我不明白。上面的代码只有在CodeGear提供修复程序并释放变量Values和Keys且之后不将它们设置为nil时才会存在危险。但这是你所能做的最好的方法。绝对比在释放它们后没有将其设置为nil并调用inherited更好。 - Heinrich Ulbricht

0

在创建字典时使用此参数,它将释放对象。

TObjectDictionary<string, TMyClass>.Create([doOwnsValues]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接