TList抛出异常
我有以下代码:
program Tlist;
{$APPTYPE CONSOLE}
{$R *.res}
uses
madExcept,
madLinkDisAsm,
madListHardware,
madListProcesses,
madListModules,
System.Generics.Collections,
System.SysUtils;
type
TMyItem = class(TInterfacedObject)
private
ItemPrice: Currency;
public
constructor Create(const aItemPrice: Currency); reintroduce;
end;
IMyList = interface
['{1D11BD29-5C1E-4171-B67E-FB9157DCB021}']
function Reset(const aItems: Integer): Integer;
function Add(const aPrice, aItemN: Integer): Integer;
end;
TMyList = class(TInterfacedObject, IMyList)
private
FList: array of TList<TMyItem>;
public
function Reset(const aItems: Integer): Integer;
function Add(const aPrice, aItemN: Integer): Integer;
end;
{ TMyList }
function TMyList.Add(const aPrice, aItemN: Integer): Integer;
begin
FList[aItemN].Add(TMyItem.Create(aPrice));
Result := FList[aItemN].Count;
end;
function TMyList.Reset(const aItems: Integer): Integer;
var
I: Integer;
begin
SetLength(FList, 0);
SetLength(FList, aItems);
for I := 0 to Length(FList) - 1 do
begin
FList[I] := TList<TMyItem>.Create;
end;
Result := Length(FList);
end;
{ TMyItem }
constructor TMyItem.Create(const aItemPrice: Currency);
begin
ItemPrice := aItemPrice;
end;
var
MyList: IMyList;
begin
MyList := TMyList.Create;
MyList.Reset(3);
mylist.Add(1000, 1);
end.
执行时,它会抛出链接到 TList
的异常。
由于 TList
实现了引用计数,并且所有类均派生自 TInterfacedObject
我的印象是内存会自动释放,但显然,我错了。
我做错了什么?
编辑
根据建议,我想出了以下代码:
program Tlist2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
madExcept,
madLinkDisAsm,
madListHardware,
madListProcesses,
madListModules,
System.Generics.Collections,
System.SysUtils;
type
IMyItem = interface
['{2EB53CC3-E5FC-474B-A162-30BBD2D17C48}']
end;
TMyItem = class(TInterfacedObject, IMyItem )
private
ItemPrice: Currency;
public
constructor Create(const aItemPrice: Currency); reintroduce;
end;
IMyList = interface
['{1D11BD29-5C1E-4171-B67E-FB9157DCB021}']
function Reset(const aItems: Integer): Integer;
function Add(const aPrice, aItemN: Integer): Integer;
end;
TMyList = class(TInterfacedObject, IMyList)
private
FList: array of TList<TMyItem>;
public
function Reset(const aItems: Integer): Integer;
function Add(const aPrice, aItemN: Integer): Integer;
destructor Destroy; override;
end;
{ TMyList }
function TMyList.Add(const aPrice, aItemN: Integer): Integer;
begin
FList[aItemN].Add(TMyItem.Create(aPrice));
Result := FList[aItemN].Count;
end;
destructor TMyList.Destroy;
var
I: Integer;
a: Integer;
begin
for I := 0 to Length(FList) - 1 do
begin
if FList[I].Count > 0 then
begin
for a := 0 to FList[I].Count - 1 do
begin
FList[I][a].Destroy
end;
end;
FList[I].Destroy;
end;
inherited;
end;
function TMyList.Reset(const aItems: Integer): Integer;
var
I: Integer;
begin
SetLength(FList, 0);
SetLength(FList, aItems);
for I := 0 to Length(FList) - 1 do
begin
FList[I] := TList<TMyItem>.Create;
end;
Result := Length(FList);
end;
{ TMyItem }
constructor TMyItem.Create(const aItemPrice: Currency);
begin
ItemPrice := aItemPrice;
end;
var
MyList: IMyList;
begin
MyList := TMyList.Create;
MyList.Reset(3);
mylist.Add(1000, 1);
end.
工作正常,不再有内存泄漏,但我觉得我在这里错过了一些东西。 我认为通过使用接口并从 TInterfacedObject
派生我的类,销毁器就不是必需的了。
I have the following code:
program Tlist;
{$APPTYPE CONSOLE}
{$R *.res}
uses
madExcept,
madLinkDisAsm,
madListHardware,
madListProcesses,
madListModules,
System.Generics.Collections,
System.SysUtils;
type
TMyItem = class(TInterfacedObject)
private
ItemPrice: Currency;
public
constructor Create(const aItemPrice: Currency); reintroduce;
end;
IMyList = interface
['{1D11BD29-5C1E-4171-B67E-FB9157DCB021}']
function Reset(const aItems: Integer): Integer;
function Add(const aPrice, aItemN: Integer): Integer;
end;
TMyList = class(TInterfacedObject, IMyList)
private
FList: array of TList<TMyItem>;
public
function Reset(const aItems: Integer): Integer;
function Add(const aPrice, aItemN: Integer): Integer;
end;
{ TMyList }
function TMyList.Add(const aPrice, aItemN: Integer): Integer;
begin
FList[aItemN].Add(TMyItem.Create(aPrice));
Result := FList[aItemN].Count;
end;
function TMyList.Reset(const aItems: Integer): Integer;
var
I: Integer;
begin
SetLength(FList, 0);
SetLength(FList, aItems);
for I := 0 to Length(FList) - 1 do
begin
FList[I] := TList<TMyItem>.Create;
end;
Result := Length(FList);
end;
{ TMyItem }
constructor TMyItem.Create(const aItemPrice: Currency);
begin
ItemPrice := aItemPrice;
end;
var
MyList: IMyList;
begin
MyList := TMyList.Create;
MyList.Reset(3);
mylist.Add(1000, 1);
end.
When executed, it throws an exception linked to TList<T>
.
As TList
implements the reference counting and all the classes are derived from TInterfacedObject
I was under the impression that the memory would be released automatically but obviously, I am wrong.
What am I doing wrong?
EDIT
Following the suggestions I came up with the following code:
program Tlist2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
madExcept,
madLinkDisAsm,
madListHardware,
madListProcesses,
madListModules,
System.Generics.Collections,
System.SysUtils;
type
IMyItem = interface
['{2EB53CC3-E5FC-474B-A162-30BBD2D17C48}']
end;
TMyItem = class(TInterfacedObject, IMyItem )
private
ItemPrice: Currency;
public
constructor Create(const aItemPrice: Currency); reintroduce;
end;
IMyList = interface
['{1D11BD29-5C1E-4171-B67E-FB9157DCB021}']
function Reset(const aItems: Integer): Integer;
function Add(const aPrice, aItemN: Integer): Integer;
end;
TMyList = class(TInterfacedObject, IMyList)
private
FList: array of TList<TMyItem>;
public
function Reset(const aItems: Integer): Integer;
function Add(const aPrice, aItemN: Integer): Integer;
destructor Destroy; override;
end;
{ TMyList }
function TMyList.Add(const aPrice, aItemN: Integer): Integer;
begin
FList[aItemN].Add(TMyItem.Create(aPrice));
Result := FList[aItemN].Count;
end;
destructor TMyList.Destroy;
var
I: Integer;
a: Integer;
begin
for I := 0 to Length(FList) - 1 do
begin
if FList[I].Count > 0 then
begin
for a := 0 to FList[I].Count - 1 do
begin
FList[I][a].Destroy
end;
end;
FList[I].Destroy;
end;
inherited;
end;
function TMyList.Reset(const aItems: Integer): Integer;
var
I: Integer;
begin
SetLength(FList, 0);
SetLength(FList, aItems);
for I := 0 to Length(FList) - 1 do
begin
FList[I] := TList<TMyItem>.Create;
end;
Result := Length(FList);
end;
{ TMyItem }
constructor TMyItem.Create(const aItemPrice: Currency);
begin
ItemPrice := aItemPrice;
end;
var
MyList: IMyList;
begin
MyList := TMyList.Create;
MyList.Reset(3);
mylist.Add(1000, 1);
end.
That works fine, no more memory leaks BUT I am under the impression that I am missing out on something here.
I thought that by using interfaces and deriving my classes from TInterfacedObject
the destroyer would not be necessary.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据 David 和 Remi 的意见,我修改了我的代码:
没有内存泄漏。
Following the input from David and Remi I have amended my code:
No memory leaks.