2009-02-04 1 views
3

Я только что рассмотрел использование нового типа TDictionary. Но на QualityCentral я прочитал о две утечки памяти, вызванные TDictionary:Утечка памяти в TDictionary - Проблемы с обходным решением?

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

Я просто реализован предлагаемый обходной путь, в основном подклассов TDictionary, перекрывая деструктор и вручную freing два объекта, которые вызывают утечку:

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

Проблема в том, что значения и ключи являются доступными только для чтения свойствами TDictionary, я не могу установить их в nil. Ну, просто чтобы быть ясным, все отлично работает сейчас, но я подумал, что произойдет, если CodeGear выпустит патч для утечки и снова освободит два объекта в своем собственном деструкторе. Разве это не привело бы к нарушению доступа?

Заранее благодарим за чтение (и, надеюсь, ответ).

+0

Спасибо за ответ. Хотя мне не очень нравится, когда я полагаюсь на кого-то другого, устанавливающего все объекты на нуль, освободив их. Или я здесь параноик? – jpfollenius

+0

Я знаю, что вы имеете в виду и согласитесь. Если бы я был вами, я снова посмотрел бы на исходный код, когда проблема будет устранена в горячем исправлении или пакете обновления - просто чтобы быть уверенным. И я надеюсь, что исправления скоро появятся, потому что в TDictionary есть и другие серьезные ошибки, которые необходимо срочно исправлять. –

+0

Также обратите внимание на то, что на данный момент вам следует избегать использования TDictionary из-за ошибки в методе Clear и его ужасной добавленной производительности. См. Здесь для получения дополнительной информации: http://alex.ciobanu.org/?p=59 –

ответ

2

Вы могли бы назвать inherited первым и проверить, если свойства по-прежнему задаются:

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

И кстати: Free не волнует, если экземпляр будет освобожден в nil, так что это будет работать, если (но только если) inherited Destroy задает свойства nil.

+0

Это опасно, так как унаследованные будут иметь свободную память, которую вы ссылаетесь впоследствии. Просто. Вполне нормально, поскольку он автоматически проверяет нуль. – mj2008

+0

Не понимаю. Вышеприведенный код опасен только в том случае, если CodeGear предоставляет исправление, которое освобождает переменные Values ​​и Keys и НЕ устанавливает их после этого. Но это лучшее, что вы можете сделать. Это определенно лучше, чем освобождать их, не устанавливая их на ноль и не называя их потом. –

0

Я не знаю, как насчет предыдущих версий Delphi, но в XE5 есть класс TObjectDictionary, который заботится о освобождении всех подэлементов.

+0

Как вы можете видеть в элементе контроля качества, проблема была решена в сборке 12.0.3299.19016. Это означает, что пользователи Delphi 2009 должны проверить свою используемую сборку (см. Тег вопроса), и все пользователи с более новыми версиями должны быть в порядке. – sausagequeen