TDAMemDataTable, problem using cloned tables

Hello,

i’ve discovered a bug in using clone tables. The problem occurs when i get two tables cloned to one clonesource, then open only one of them, release an instance of the second and then later i release the CloneSource. In attached sample, you can simulate the problem but because there’s not much data in the sample, it doesn’t really ends with an Access Violation even if method of freed object is called.

DASample_CloneRegister.zip (1.5 KB)

As you can see in the “FreeAndNil(LCloneSource)”, it’s TDAMemoryDataset’s method UnregisterAllClients is called and there is still reference to LClone2 instance in his FCloneClientList even if it doesn’t exist anymore.

I think the cause of the problem rests in TDAMemoryDataset.RegisterPermanentClients method which should register just opened clients and should be fixed in this way:

procedure TDAMemoryDataset.RegisterPermanentClients;
var
  lClient: TDAMemoryDataset;
  i: integer;
  llist: TList;
begin
  if FClonePermanentClientList <> nil then begin
    llist := FClonePermanentClientList.LockList;
    try
      For I := 0 to llist.Count - 1 do begin
        lClient:= TDAMemoryDataset(llist.Items[i]);
        if Assigned(lClient) {FIX HERE} and LClient.Active {FIX HERE} then begin
          RegisterClient(lClient);
          lClient.RegisterPermanentClients;
        end;
      end;
    finally
      FClonePermanentClientList.UnlockList;
    end;
  end;
end;

Regards from Prague,
Jaroslav

Your testcase works without any errors. Can you recheck it, pls?

Please replace fmCloneSource.pas from previous Sample project. As i wrote in the last reply, the problem doesn’t occur in the demo but it’s clear to see in UnregisterAllClients. But in attached sample i have forced delphi to really overwrite memory of original LClone2 instance that has been freed before.

fmCloneSource.pas (1.5 KB)

Thanks, logged as bugs://71532

correct fix will be

procedure TDAMemoryDataset.UnregisterPermanentClient(
  const AClient: TDAMemoryDataset);
begin
  if FClonePermanentClientList <> nil then
    FClonePermanentClientList.Remove(AClient);
  if FCloneClientList <> nil then FCloneClientList.Remove(AClient);  //added
end;

bugs://71532 got closed with status fixed.