Oop TObjectList.DisposeOf上的指针操作无效
大家好,如果这是一个重复的,很抱歉,但我的具体问题,我还没有看到回答任何地方。 当我尝试释放运行时在以下行创建的ObjectList时,我遇到了“无效指针操作”:Oop TObjectList.DisposeOf上的指针操作无效,oop,delphi,tobjectlist,Oop,Delphi,Tobjectlist,大家好,如果这是一个重复的,很抱歉,但我的具体问题,我还没有看到回答任何地方。 当我尝试释放运行时在以下行创建的ObjectList时,我遇到了“无效指针操作”: Prods := TItemProcedimento.Create(DM.FDQ).lerProdutos; Prods.DisposeOf; // <- Invalid Pointer Operation at 2nd iteration 为什么??我做错了什么?这个测试代码是在当前代码之前运行的,顺便说一句,可能是
Prods := TItemProcedimento.Create(DM.FDQ).lerProdutos;
Prods.DisposeOf; // <- Invalid Pointer Operation at 2nd iteration
为什么??我做错了什么?这个测试代码是在当前代码之前运行的,顺便说一句,可能是相关的吗
更新:
通过应用Remy Lebeau建议的更改,我成功地将项目正确地添加到列表中,并对其进行处理,从而使代码的这一特定部分没有泄漏。但在代码的另一部分,我有一个ObjectList漏洞,我不知道如何修复
在我的类中,我有一个属性是TObjectList属性,我有一个方法检查列表是否已分配,如果未分配,它将创建列表并将其返回给调用列表的人
[...]
type
TProcedimento = class
private
[...]
FPRC_Produtos: TObjectList<TItemProcedimento>;
public
[...]
function getPRC_Produtos: TObjectList<TItemProcedimento>;
function criaProcedimentos: TObjectList<TProcedimento>;
[...]
function TProcedimento.GetPRC_Produtos: TObjectList<TItemProcedimento>;
begin
if not Assigned(FPRC_Produtos) then
FPRC_Produtos:= TObjectList<TItemProcedimento>.Create;
result := FPRC_Produtos;
end;
function TProcedimento.criaProcedimentos: TObjectList<TProcedimento>;
var
IPR: TItemProcedimento;
Procedimento: TProcedimento;
ds: TFDQuery;
begin
result := TObjectList<TProcedimento>.Create;
ds := TFDQuery.Create(nil);
ds.Connection := FDataSet.Connection;
IPR := TItemProcedimento.Create(ds);
try
FDataSet.Close;
FDataSet.Open('SELECT * FROM Procedimento');
while not FDataSet.Eof do
begin
Procedimento := TProcedimento.Create(FDataSet);
Procedimento.PRC_ID := FDataSet.FieldByName('PRC_ID').AsInteger;
Procedimento.PRC_Nome := FDataSet.FieldByName('PRC_Nome').AsString;
Procedimento.PRC_Duracao := FDataSet.FieldByName('PRC_Duracao')
.AsDateTime;
Procedimento.PRC_Preco := FDataSet.FieldByName('PRC_Preco').AsCurrency;
Procedimento.PRC_Custo := FDataSet.FieldByName('PRC_Custo').AsCurrency;
Procedimento.PRC_Consumo := FDataSet.FieldByName('PRC_Consumo').AsFloat;
Procedimento.FPRC_Produtos := IPR.getItensProcedimento(FPRC_ID);
result.Add(Procedimento);
FDataSet.Next;
end;
finally
FDataSet.Close;
IPR.DisposeOf;
ds.DisposeOf;
end;
end;
如何解决此问题?可能的结果。添加(self);是罪魁祸首。将同一对象多次添加到对象列表中。当您多次销毁自由列表对象时。您应该为添加到列表中的每个项目创建新对象。在调试方面,它工作得很好:我的数据库中有4个项目,当我运行此代码时,它仅成功创建了1个ObjectList和该列表中的4个项目。另外,我在另一个类中有完全相同的代码,在那里它不会抛出无效指针错误,这是令人困惑的me@Mobiusone但这4个列表项只指向内存中的1个对象(
Self
)。您需要创建4个不同的titemprocedmento
对象,例如让while
循环执行以下操作:var NewItem:titemprocedmento。。。而不是FDataSet.Eof do begin NewItem:=titemprocedmento.Create;请尝试NewItem.PRO_ID:=。。。结果。添加(新项);新项目除外。免费;提高;结束;FDataSet.Next;结束代码>好的,成功了。我不必担心销毁它们,因为ObjectList会为我处理这些,对吗?@Mobiusone是的,因为它的OwnsObjects
属性默认为true。
test := TMyClass.Create(DM.FDQ).lerTeste;
test.DisposeOf;
[...]
type
TProcedimento = class
private
[...]
FPRC_Produtos: TObjectList<TItemProcedimento>;
public
[...]
function getPRC_Produtos: TObjectList<TItemProcedimento>;
function criaProcedimentos: TObjectList<TProcedimento>;
[...]
function TProcedimento.GetPRC_Produtos: TObjectList<TItemProcedimento>;
begin
if not Assigned(FPRC_Produtos) then
FPRC_Produtos:= TObjectList<TItemProcedimento>.Create;
result := FPRC_Produtos;
end;
function TProcedimento.criaProcedimentos: TObjectList<TProcedimento>;
var
IPR: TItemProcedimento;
Procedimento: TProcedimento;
ds: TFDQuery;
begin
result := TObjectList<TProcedimento>.Create;
ds := TFDQuery.Create(nil);
ds.Connection := FDataSet.Connection;
IPR := TItemProcedimento.Create(ds);
try
FDataSet.Close;
FDataSet.Open('SELECT * FROM Procedimento');
while not FDataSet.Eof do
begin
Procedimento := TProcedimento.Create(FDataSet);
Procedimento.PRC_ID := FDataSet.FieldByName('PRC_ID').AsInteger;
Procedimento.PRC_Nome := FDataSet.FieldByName('PRC_Nome').AsString;
Procedimento.PRC_Duracao := FDataSet.FieldByName('PRC_Duracao')
.AsDateTime;
Procedimento.PRC_Preco := FDataSet.FieldByName('PRC_Preco').AsCurrency;
Procedimento.PRC_Custo := FDataSet.FieldByName('PRC_Custo').AsCurrency;
Procedimento.PRC_Consumo := FDataSet.FieldByName('PRC_Consumo').AsFloat;
Procedimento.FPRC_Produtos := IPR.getItensProcedimento(FPRC_ID);
result.Add(Procedimento);
FDataSet.Next;
end;
finally
FDataSet.Close;
IPR.DisposeOf;
ds.DisposeOf;
end;
end;
procedure TKBForm1.CarregaProcedimento;
var
Procedimento: TProcedimento;
Procs: TObjectList<TProcedimento>;
[...]
begin
Procs := TProcedimento.Create(DM.FDQ).criaProcedimentos;
try
LV_Procedimento.Items.Clear;
LV_Procedimento.BeginUpdate;
for Procedimento in Procs do
begin
with LV_Procedimento.Items.Add do
[...]
finally
Procs.DisposeOf;
Procedimento.GetPRC_Produtos.DisposeOf;
end;
end;
73 - 88 bytes: TProcedimento x 1, TItemProcedimento x 2