Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop TObjectList.DisposeOf上的指针操作无效_Oop_Delphi_Tobjectlist - Fatal编程技术网

Oop TObjectList.DisposeOf上的指针操作无效

Oop TObjectList.DisposeOf上的指针操作无效,oop,delphi,tobjectlist,Oop,Delphi,Tobjectlist,大家好,如果这是一个重复的,很抱歉,但我的具体问题,我还没有看到回答任何地方。 当我尝试释放运行时在以下行创建的ObjectList时,我遇到了“无效指针操作”: Prods := TItemProcedimento.Create(DM.FDQ).lerProdutos; Prods.DisposeOf; // <- Invalid Pointer Operation at 2nd iteration 为什么??我做错了什么?这个测试代码是在当前代码之前运行的,顺便说一句,可能是

大家好,如果这是一个重复的,很抱歉,但我的具体问题,我还没有看到回答任何地方。 当我尝试释放运行时在以下行创建的ObjectList时,我遇到了“无效指针操作”:

  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