Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Generics - Memory Leak wenn constructor ohne inherited Create (https://www.delphipraxis.net/199994-generics-memory-leak-wenn-constructor-ohne-inherited-create.html)

Cashew 8. Mär 2019 16:25

Generics - Memory Leak wenn constructor ohne inherited Create
 
Hallo zusammen,

ich denk mal dass die Klassenstruktur aus dem folgenden Beispielgängige Praxis ist:

Delphi-Quellcode:
  { TMyItem }
  //----------------------------------------------------------------------------
  TMyItem = class
  private
    FInfo : string;
  public
    constructor Create;
    destructor Destroy; override;
    property Info : string read FInfo write FInfo;
  end;

  { TMyItems }
  //----------------------------------------------------------------------------
  TMyItems = class (TObjectList<TMyItem>)
  public
    constructor Create;
    destructor Destroy; override;
    procedure AddItem(const AValue:TMyItem);
  end;

Ich habe heute in meinem Programm, in der *.dpr Datei die Option ReportMemoryLeaksOnShutdown eingeschaltet. Und habe beim Schließen der Anwendung dann die Info bekommen, das ich "Speicherlöcher" habe... Hervorgerufen durch nicht freigegebene TMyItem Instanzen...

Ich bin dann darauf gekommen, dass der Fehler an meinem constructor von der Klasse TMyItems liegt. Denn hatte ich wie folgt implementiert:

Delphi-Quellcode:
constructor TMyItems.Create;
begin
  inherited;
end;
Nachdem ich dann das inherited; auf inherited Create; geändert hatte waren meine "Speicherlöcher" weg...

Woran liegt das? Ich dachte das die Angabe von inherited ausreichend ist... Oder bin ich da heut gedanklich auf dem Holzweg?

Der schöne Günther 8. Mär 2019 17:53

AW: Generics - Memory Leak wenn constructor ohne inherited Create
 
Das bringt immer wieder die armen Benutzer von
Delphi-Quellcode:
TList<T>
bzw.
Delphi-Quellcode:
TObjectList<T>
zur Verzweiflung.

Wenn du in deinem parameterlosen Konstruktor Create einfach sagst
Delphi-Quellcode:
inherited
dann ruft er den parameterlosen Konstruktor der Oberklasse auf.


Schau mal: Hat
Delphi-Quellcode:
TObjectList<TMyItem>
denn einen? Nein, hat es nicht! Es hat einen mit einem Parameter den man weglassen kann. Wenn du sagst
Delphi-Quellcode:
inherited Create()
dann füllt der Compiler den optionalen Parameter für dich aus und der richtige Konstruktor mit dem optionalen Parameter wird aufgerufen.

Der Konstruktor mit "wirklich keine Parameter" ist der von TObject. Definitiv der falsche.


Das Problem manifestiert sich auch an ganz anderen Stellen (z.B. wenn du eine TList<T> de-serialisieren willst), es wurde schon x mal an Embarcadero herangetragen, aber die meinen alles ist as designed

TurboMagic 8. Mär 2019 18:34

AW: Generics - Memory Leak wenn constructor ohne inherited Create
 
Hm, könnte nicht EMBT diesen TList<T> und TObjectList<T> Klassen einfach einen parameterlosen Create constructor spendieren, der intern dann denn mit dem optionalen parameter passend aufruft, falls nötig?

Wäre das ein funktionierender Lösungsansatz?

Der schöne Günther 8. Mär 2019 19:02

AW: Generics - Memory Leak wenn constructor ohne inherited Create
 
Ohne lange drüber nachgedacht zu haben würde das sicher dieses (und andere) Probleme lösen.

Noch besser wäre es, sich Standard-Parameter abzugewöhnen. Das geben Coding-Standards wie MISRA/AUTOSAR (M8-3-1), HIC++ (Kap. 9.1.2) oder Google auch sicher nicht grundlos so vor (zumindest bei virtuellen Methoden).

TurboMagic 9. Mär 2019 17:34

AW: Generics - Memory Leak wenn constructor ohne inherited Create
 
Dann stimmt doch mal fleissig hierfür:
https://quality.embarcadero.com/browse/RSP-23943

Falls man den Report noch verbessern kann einfach hier melden...

jaenicke 9. Mär 2019 19:12

AW: Generics - Memory Leak wenn constructor ohne inherited Create
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1427366)
Noch besser wäre es, sich Standard-Parameter abzugewöhnen. Das geben Coding-Standards wie MISRA/AUTOSAR (M8-3-1), HIC++ (Kap. 9.1.2) oder Google auch sicher nicht grundlos so vor (zumindest bei virtuellen Methoden).

Das liegt auch daran, dass diverse IDEs bzw. Texteditoren die möglichen Parameter schlechter darstellen als Delphi. In Delphi tragen Standard-Parameter eher zur Lesbarkeit bei.
Dass die Standard-Parameter je nach Überladung anders definiert sein können, ist sicher richtig, aber wenn der Parameter für den eigenen Code relevant ist, gibt man ihn ja auch an.

bcvs 11. Mär 2019 09:49

AW: Generics - Memory Leak wenn constructor ohne inherited Create
 
Zitat:

Zitat von Cashew (Beitrag 1427352)

Nachdem ich dann das inherited; auf inherited Create; geändert hatte waren meine "Speicherlöcher" weg...

Woran liegt das? Ich dachte das die Angabe von inherited ausreichend ist... Oder bin ich da heut gedanklich auf dem Holzweg?

Ich bin da kürzlich in die selbe Falle reingetappt:
https://www.delphipraxis.net/199595-...inherited.html

Stevie 11. Mär 2019 12:03

AW: Generics - Memory Leak wenn constructor ohne inherited Create
 
Und genau deshalb hat man sich damals bei C# entschieden, dass Konstruktoren nicht vererbt werden.

Cashew 12. Mär 2019 07:41

AW: Generics - Memory Leak wenn constructor ohne inherited Create
 
Vielen Dank für die Erklärungen und Links :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:33 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