Delphi XE6 - 我正在使用 TObjectDictionary 和自定义类。我创建、添加,然后免费。只要我这样做,一切就都很好。如果我执行“TryGetValue”,我会收到“无效指针操作”。 TryGetValue 工作正常,给出了正确的结果,但稍后会导致问题......
这是我的代码。
type
TWordRec = class
public
RemoveAlways: Boolean; // Is this CORP LLC, etc?
RemoveRestricted: Boolean;
Replace: Boolean;
ReplaceWith: string;
Constructor Create(B1, B2, B3: Boolean; S1: String); overload;
end;
...
constructor TWordRec.Create(B1, B2, B3: Boolean; S1: String);
begin
self.RemoveAlways := B1; // Is this CORP LLC, etc?
self.RemoveRestricted := B2;
self.Replace := B3;
self.ReplaceWith := S1;
end;
我在按钮上添加测试代码...
procedure TForm1.Button1Click(Sender: TObject);
var
CurrentDictEntry : TWordRec;
FoundIt : Boolean;
begin
ReportMemoryLeaksOnShutdown := True;
WordDict := TObjectDictionary<String, TWordRec>.Create([doOwnsValues]);
WordDict.Add('CO', TWordRec.Create(True, False, False, ''));
WordDict.Add('CORP', TWordRec.Create(True, False, False, ''));
WordDict.Add('CORPORATION', TWordRec.Create(True, False, False, ''));
CurrentDictEntry := TWordRec.Create(False, False, False, '');
// If I remove next two code lines, everything is fine
// With these 2 lines, I get error ON WordDict.Free;
FoundIt := WordDict.TryGetValue('CORP', CurrentDictEntry);
if FoundIt = True then ShowMessage('Found');
CurrentDictEntry.Free;
WordDict.Free;
end;
为什么我无法释放我的 WordDict?如果我只是释放 WordDict(即注释掉 CurrentDictEntry.free),则 WordDict.Free 可以在没有无效指针操作的情况下工作,但退出应用程序时会出现内存泄漏。
最佳答案
主要问题在这里:
CurrentDictEntry.Free;
此时,CurrentDictEntry
是包含在容器中的值。并且您无法释放此容器中的值,因为容器拥有它们。如果您尝试释放值,那么容器稍后将尝试再次释放它们,这是典型的双重释放问题。
一旦你告诉容器拥有这些值,你就不能释放它们。
另一个问题是您泄漏了 TWordRec
。
CurrentDictEntry := TWordRec.Create(False, False, False, '');
FoundIt := WordDict.TryGetValue('CORP', CurrentDictEntry);
第一行创建一个新对象并在 CurrentDictEntry
中保存对其的引用。然后,第二行覆盖 CurrentDictEntry
,现在您根本没有对刚刚创建的对象的引用,因此它被泄漏。
您的代码应如下所示:
ReportMemoryLeaksOnShutdown := True;
WordDict := TObjectDictionary<String, TWordRec>.Create([doOwnsValues]);
try
WordDict.Add('CO', TWordRec.Create(True, False, False, ''));
WordDict.Add('CORP', TWordRec.Create(True, False, False, ''));
WordDict.Add('CORPORATION', TWordRec.Create(True, False, False, ''));
FoundIt := WordDict.TryGetValue('CORP', CurrentDictEntry);
if FoundIt then
ShowMessage('Found');
finally
WordDict.Free;
end;
关于Delphi - TObjectDictionary 在免费时给出无效指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25645077/