AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein [ARC] Clipper Arrayübergabe hat MemoryLeaks

[ARC] Clipper Arrayübergabe hat MemoryLeaks

Ein Thema von Rollo62 · begonnen am 24. Mai 2016 · letzter Beitrag vom 24. Mai 2016
Antwort Antwort
Rollo62

Registriert seit: 15. Mär 2007
3.969 Beiträge
 
Delphi 12 Athens
 
#1

[ARC] Clipper Arrayübergabe hat MemoryLeaks

  Alt 24. Mai 2016, 19:42
Hallo zusammen,

ich versucher gerade die Clipper Library von Angus Johnson
auf Fmx und Mobile zu adaptieren.
Da bekomme ich aber noch so unschöne MemoryLeaks, die man leider schlecht verifizieren kann.

Soweit hatte ich diese Klasse ausgemacht, wo Arrays und ArryOfArry benutzt wird um die Child-Knoten zu speichern.

Delphi-Quellcode:
  TPolyNode = class;
  TArrayOfPolyNode = array of TPolyNode;

  TPolyNode = class
  private
    FPath : TPath;
    FParent : TPolyNode;
    FIndex : Integer;
    FCount : Integer;
    FBuffLen : Integer;
    FIsOpen : Boolean;
    FChilds : TArrayOfPolyNode;
    FJoinType: TJoinType; //used by ClipperOffset only
    FEndType : TEndType; //used by ClipperOffset only
    function GetChild(Index: Integer): TPolyNode;
    function IsHoleNode: boolean;
    procedure AddChild(PolyNode: TPolyNode);
    function GetNextSiblingUp: TPolyNode;
  public
    function GetNext: TPolyNode;
    property ChildCount: Integer read FCount;
    property Childs[index: Integer]: TPolyNode read GetChild;
    property Parent: TPolyNode read FParent;
    property IsHole: Boolean read IsHoleNode;
    property IsOpen: Boolean read FIsOpen;
    property Contour: TPath read FPath;
  end;

function TPolyNode.GetChild(Index: Integer): TPolyNode;
begin
  if (Index < 0) or (Index >= FCount) then
    raise Exception.Create('TPolyNode range error: ' + inttostr(Index));
  Result := FChilds[Index];
end;


procedure TPolyNode.AddChild(PolyNode: TPolyNode);
begin
  if FCount = FBuffLen then
  begin
    Inc(FBuffLen, 16);
    SetLength(FChilds, FBuffLen);
  end;
  PolyNode.FParent := self;
  PolyNode.FIndex := FCount;
  FChilds[FCount] := PolyNode; //<-- Hier vermute ich das eine Referenz übergeben wird, und nicht wieder freigegeben wird
  Inc(FCount);
end;
Benutzt wird es dann z.B. hier
Delphi-Quellcode:
procedure TClipperOffset.AddPath(const Path: TPath;
  JoinType: TJoinType; EndType: TEndType);
var
  I, J, K, HighI: Integer;
  NewNode: TPolyNode;
  ip: TIntPoint;
begin
  HighI := Length(Path)-1; //S4:
  if HighI < 0 then Exit;
  NewNode := TPolyNode.Create; //<-- CREATE hier wird ein Node angelegt
  NewNode.FJoinType := JoinType;
  NewNode.FEndType := EndType;

  //strip duplicate points from path and also get index to the lowest point ...
  if EndType in [etClosedLine, etClosedPolygon] then
    while (HighI > 0) and PointsEqual(Path[0], Path[HighI]) do dec(HighI);
  SetLength(NewNode.FPath, HighI +1);
  NewNode.FPath[0] := Path[0];
  J := 0; K := 0;
  for I := 1 to HighI do
    if not PointsEqual(NewNode.FPath[J], Path[I]) then
    begin
      inc(J);
      NewNode.FPath[J] := Path[I];
      if (NewNode.FPath[K].Y < Path[I].Y) or
        ((NewNode.FPath[K].Y = Path[I].Y) and
        (NewNode.FPath[K].X > Path[I].X)) then
          K := J;
    end;
  inc(J);
  if J < HighI +1 then
    SetLength(NewNode.FPath, J);
  if (EndType = etClosedPolygon) and (J < 3) then
  begin
    NewNode.free; //<-- Hier wird etwas freigegeben
    Exit;
  end;
  FPolyNodes.AddChild(NewNode); //<-- hier wird der NewNode übergeben, uns sollte dann nur in den PolyNodes referenziert sein

  if EndType <> etClosedPolygon then Exit;
  //if this path's lowest pt is lower than all the others then update FLowest
  if (FLowest.X < 0) then
  begin
    FLowest := IntPoint(FPolyNodes.ChildCount -1, K);
  end else
  begin
    ip := FPolyNodes.Childs[FLowest.X].FPath[FLowest.Y];
    if (NewNode.FPath[K].Y > ip.Y) or
      ((NewNode.FPath[K].Y = ip.Y) and
      (NewNode.FPath[K].X < ip.X)) then
        FLowest := IntPoint(FPolyNodes.ChildCount -1, K);
  end;
end;


procedure TClipperOffset.AddPaths(const Paths: TPaths;
  JoinType: TJoinType; EndType: TEndType);
var
  I: Integer;
begin
  for I := 0 to Length(Paths)-1 do
    AddPath(Paths[I], JoinType, EndType);
end;

Leider ist der Code etwas unübersichtlich und unüblich, deshalb sehe ich den Wald vor Bäumen nicht mehr.
Sieht vielleicht jemand den Fehler im Bild, oder hat schon jemand diese Library portiert ?
Ich brauche davon eigentlich nur die Offset/Inflate Routine des Polygons, es scheint aber das diese ClipperLibrary das einzige auf weiter Flur ist was das sauber lösen kann.

Wie gesagt, es funktioniert alles Super, auch unter IOS/Android, nur das ich unter iOS(android ?) MemoryLeaks bekomme.
Und Apple versteht da keinen Spass.


Siehe hier:
Zitat:
Leaked Object # Address Size Responsible Library Responsible Frame
Clipper::TClipper 1 0x15c3f2f90 144 Bytes TestNote Clipper::TClipperOffset::Clear()
Clipper::TClipper 1 0x15c3efb80 144 Bytes TestNote Clipper::TClipperOffset::Clear()
Malloc 80 Bytes 1 0x15c3e8b90 80 Bytes TestNote Clipper::TClipperOffset::AddPath(System:ynamicAr ray<Clipper::TIntPoint>, Clipper::TJoinType, Clipper::TEndType)
Clipper::TPolyNode 1 0x15c38a800 80 Bytes TestNote Clipper::TClipperOffset::AddPath(System:ynamicAr ray<Clipper::TIntPoint>, Clipper::TJoinType, Clipper::TEndType)
Clipper::TPolyNode 1 0x15c3f3970 80 Bytes TestNote Clipper::TClipperOffset::TClipperOffset(double, double)
Malloc 64 Bytes 1 0x15c394950 64 Bytes TestNote Clipper::TClipperOffset::AddPath(System:ynamicAr ray<Clipper::TIntPoint>, Clipper::TJoinType, Clipper::TEndType)
Malloc 64 Bytes 2 < multiple > 128 Bytes TestNote Clipper::TClipperOffset::AddPath(System:ynamicAr ray<Clipper::TIntPoint>, Clipper::TJoinType, Clipper::TEndType)
Clipper::TPolyNode 2 < multiple > 160 Bytes TestNote Clipper::TClipperOffset::AddPath(System:ynamicAr ray<Clipper::TIntPoint>, Clipper::TJoinType, Clipper::TEndType)
Clipper::TPolyNode 1 0x15c381a70 80 Bytes TestNote Clipper::TClipperOffset::AddPath(System:ynamicAr ray<Clipper::TIntPoint>, Clipper::TJoinType, Clipper::TEndType)
Clipper::TPolyNode 2 < multiple > 160 Bytes TestNote Clipper::TClipperOffset::TClipperOffset(double, double)
Clipper::TClipper 2 < multiple > 288 Bytes TestNote Clipper::TClipperOffset::Clear()
Clipper::TPolyNode 1 0x15c3ec7c0 80 Bytes TestNote Clipper::TClipperOffset::TClipperOffset(double, double)
P.S. Die Smilies sind nicht von mir, sondern aus dem Instruments Tool. Ich könnte heulen

Rollo
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: [ARC] Clipper Arrayübergabe hat MemoryLeaks

  Alt 24. Mai 2016, 20:09
Und wenn du das mal einfügst?
Delphi-Quellcode:
TPolyNode = class
  private
    FPath : TPath;
    [weak] // prevents ARC circular reference
    FParent : TPolyNode;
    FIndex : Integer;
    FCount : Integer;
  ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.969 Beiträge
 
Delphi 12 Athens
 
#3

AW: [ARC] Clipper Arrayübergabe hat MemoryLeaks

  Alt 24. Mai 2016, 20:16
Hallo Sir Rufo,

danksehr, sowas hatte ich mir schon gedacht.
Bin mit nur nicht sicher ob zuviel [Weak] nicht auch schaden kann.
Insbesondere bei so einem Spagetticode.

Gibt es da eine Faustregel, wann sollte man es NICHT anwenden ?
Kann man Weak Referenzen genau wie bisher Create/Free machen, ohne das etwas in die Hose geht ?

Werds jedenfalls gleich mal Testen.

EDIT:
Ja, du hast wie immer Recht.
Dann kann ich ja für heute den Deckel zuklappen.
Über die negativen Seiten von Weak mache ich mir dann morgen Gedanken

Rollo

Geändert von Rollo62 (24. Mai 2016 um 20:26 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:40 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz