Einzelnen Beitrag anzeigen

snook

Registriert seit: 25. Jun 2010
94 Beiträge
 
Delphi 2005 Professional
 
#1

MemLeak, aber wo???

  Alt 12. Mai 2011, 11:46
FastMM4 zeigt mir in der proc UpdateInfoTable nen leak an, genaueres zur methode wird dann aber nciht mehr angezeigt

jedenfalls sind die ganzen zugirffe auf die IDataModule leckfrei. es kann eigentlich nur irgendwie mit den PChars zu tun haben. oder ich geb nen Item (PPlugInInfoTable) nicht richtig frei. hab jetzt aber schon solange draufgestarrt, dass ich nciht mehr durchblicke.

Delphi-Quellcode:

  PPlugInInfoTable = ^TPlugInInfoTable;
  TPlugInInfoTable = packed record
    Name, Dll,
    Date, Author: PChar;
    Status : TPlugInStatus;
    GUID : PChar;
    Handle : Cardinal;
    Version : real;
  end;

function CopyPChar(Source: PChar): PChar;
var dummy: ansistring;
begin
  result := nil;
{  if length(Source) > 0 then
    StrAlloc(result, StrLen(@Source[1]) + 1)
  else
    StrAlloc(result, 1);
  StrCopy(result, Source);}

  result := StrNew(Source);
end;

function StringToPchar(s: ansistring): PChar;
begin
  if length(s) > 0 then
    result := CopyPChar(@s[1])
  else
    result := CopyPChar(nil);
end;

procedure FreePChar(Ch: PChar);
begin
  StrDispose(Ch);
  Ch := nil;
end;

procedure NewInfoItem(out PItem);
begin
  new(PPlugInInfoTable(PItem));
  with(PPlugInInfoTable(PItem)^) do
  begin
    Name := nil;
    Dll := nil;
    Date := nil;
    Author:= nil;
    GUID := nil;
    Status:= psNil;
    Handle:= 0;
  end;
end;

procedure DisposeInfoItem(PItem: PPlugInInfoTable);
begin
  if Assigned(PItem^.Name) then FreePChar(PItem^.Name);
  if Assigned(PItem^.Dll) then FreePChar(PItem^.Dll);
  if Assigned(PItem^.Date) then FreePChar(PItem^.Date);
  if Assigned(PItem^.Author) then FreePChar(PItem^.Author);
  if Assigned(PItem^.GUID) then FreePChar(PItem^.GUID);
  dispose(PItem);
  PItem := nil;
end;

procedure TPlugInMain.UpdateInfoTable;
var LAdapter: IAdapter;
    LExtAdapter: IPlugInDllAdapter;
    DataTable, PlugInTable, Entry,
    AdapterModule, AdapterEntry: IDataModule;
    PlugIn : IPlugIn;
    PItem,
    PDummy : PPlugInInfoTable;
    i,lCount: integer;
    s : string;
begin
  while FInfoTableList.Count > 0 do
  begin
    PItem := FInfoTableList[0];
    disposeInfoItem(PItem);
    FInfoTableList.Delete(0);
  end;

  FData.GetDataTableLib(DataTable);
  if Assigned(DataTable) then
    try
      DataTable.GetFirstDataModule(Entry);
      while Assigned(Entry) do
        try
          NewInfoItem(PDummy);
          PDummy^.Name := copyPChar(Entry.GetCharValue(PChar('Name')));
          PDummy^.Dll := copyPChar(Entry.GetCharValue(PChar('DLLFile')));
          FData.GetPlugInLibrary(Entry.GetCharValue(PChar('DLLFile')),PlugInTable);
          if Assigned(PlugInTable) then
            try
              PDummy^.Date := StringToPChar(
                              DateToStr(PlugInTable.GetFloatValue(PChar('Date'))) + ' ' +
                              TimeToStr(PlugInTable.GetFloatValue(PChar('Date')))
                                           );
              GetDllAdapter(PlugInTable.GetIntValue(PChar('Handle')),LAdapter);
            finally
              PlugInTable := nil;
            end;
          if Assigned(LAdapter) then
            try
              if LAdapter.QueryInterface(IPlugInDllAdapter,LExtAdapter) = 0 then
                try
                  LExtAdapter.GetPlugInTable(AdapterModule);
                  if Assigned(AdapterModule) then
                    try
                      AdapterModule.GetDataModule(PDummy^.Name,AdapterEntry);
                    finally
                      AdapterModule := nil;
                    end;
                finally
                  LextAdapter := nil;
                end;
            finally
              LAdapter := nil;
            end;
          if Assigned(AdapterEntry) then
            try
              PDummy^.Author := CopyPChar(AdapterEntry.GetCharValue(PChar('Author')));
              PDummy^.GUID := CopyPChar(AdapterEntry.GetCharValue(PChar('GUID')));
              PDummy^.Version:= AdapterEntry.GetFloatValue(PChar('Version'));
            finally
              AdapterEntry := nil;
            end;
          FData.GetPlugInLibraryTable(Entry.Name,lCount,PlugInTable);
          if Assigned(PlugInTable) then
            try
              for i := 0 to lCount - 1 do
              begin
                NewInfoItem(PItem);
                if lCount = 1 then
                  Pitem^.Name := CopyPChar(PDummy^.Name)
                else
                begin
                  s := PDummy^.Name;
                  Pitem^.Name := StringToPChar(s + '('+IntToStr(i)+')');
                end;
                Pitem^.Dll := CopyPChar(PDummy^.Dll);
                PItem^.Author := CopyPChar(PDummy^.Author);
                PItem^.GUID := CopyPChar(PDummy^.GUID);
                PItem^.Date := copyPChar(PDummy^.Date);
                PItem^.Version:= PDummy^.Version;
                FData.GetPlugIn(StrToInt(Entry.Name),i,PlugIn);
                if Assigned(PlugIn) then
                  try
                    PItem^.Handle := PLugIn.MsgHandle;
                    PItem^.Status := TPlugInStatus(IntToOrd(
                      SendMessage(PlugIn.MsgHandle,PM_QUERYSTATUS,MsgHandle,0)));
                  finally
                    PlugIn := nil;
                  end;
                FInfoTableList.Add(PItem);
              end;
              if Assigned(PItem) then
              begin
                PItem := nil;
                DisposeInfoItem(PDummy);
              end
              else
                FInfoTableList.Add(PDummy);
            finally
              PlugInTable := nil;
            end;
        finally
          DataTable.GetNextDataModule(Entry);
        end;
    finally
      DataTable := nil;
    end;
end;
  Mit Zitat antworten Zitat