我有以下代码:
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<T>的异常。
由于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派生类,驱逐舰就没有必要了。
发布于 2022-03-16 13:30:50
根据David和Remi的输入,我修改了我的代码:
program Tlist3;
{$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)
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 TObjectList<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
if Length(FList) > 0 then
begin
for I := 0 to Length(FList) - 1 do
begin
FList[I].Free;
end;
end;
inherited;
end;
function TMyList.Reset(const aItems: Integer): Integer;
var
I: Integer;
begin
if Length(FList) > 0 then
begin
for I := 0 to Length(FList) - 1 do
begin
FList[I].Free;
end;
end;
SetLength(FList, 0);
SetLength(FList, aItems);
for I := 0 to Length(FList) - 1 do
begin
FList[I] := TObjectList<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);
mylist.Add(2000, 2);
MyList.Reset(2);
mylist.Add(1000, 0);
mylist.Add(2000, 1);
end.没有内存泄漏。
https://stackoverflow.com/questions/71483943
复制相似问题