AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein noch was zu: "Nach 20/30 starts aus der IDE speicher voll"
Thema durchsuchen
Ansicht
Themen-Optionen

noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

Ein Thema von schorsch666 · begonnen am 16. Okt 2023 · letzter Beitrag vom 19. Okt 2023
Antwort Antwort
Seite 1 von 2  1 2      
schorsch666

Registriert seit: 21. Apr 2011
81 Beiträge
 
#1

noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 16. Okt 2023, 20:55
Moin @ALL,
hatte jetzt nochmal bissi zeit... und functions gefunden, die ne stringlist zurueckgeben. und laut test (siehe code) werden die auch nicht freigegeben (sagt jedenfalls "ReportMemoryLeaksOnShutdown") und ist ja auch irgendwie logisch.

kann man sowas ueberhaupt irgendwie freigeben?? werde jetzt jedenfalls alles mal auf variante 2 umstellen. vllt. hat ja jemand nen kommentar uebrig...

LG..

..de Schorsch


Delphi-Quellcode:

    function getSL: TStringList; overload;
    function getSL(var SL: TStringList): Boolean; overload;

procedure TForm1.Button1Click(Sender: TObject);
begin
  showmessage(getSL.Text);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  var sl := TStringList.Create;
  try
    getSL(sl);
    showmessage(sl.Text);
  finally
    FreeAndNil(sl);
  end;
end;

function TForm1.getSL: TStringList;
begin
  result := TStringList.Create;

  result.Add('haha');
  result.Add('hehe');
  result.Add('hihi');
  result.Add('hoho');
  result.Add('huhu');
end;

function TForm1.getSL(var SL: TStringList): Boolean;
begin
  SL.Add('haha');
  SL.Add('hehe');
  SL.Add('hihi');
  SL.Add('hoho');
  SL.Add('huhu');
end;
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 16. Okt 2023, 21:45
Du solltest aus dem var beim Parameter ein const machen, denn die Funktion soll die Referenz auf die Stringliste ja nicht ändern, sondern die Liste lediglich nutzen (füllen).

Wenn du dich um die Freigabe nicht kümmern möchtest, musst du Interfaces nutzen. Die musst du aber natürlich dann auch erst implementieren. Dann ginge auch Variante 1.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
mytbo

Registriert seit: 8. Jan 2007
472 Beiträge
 
#3

AW: noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 16. Okt 2023, 22:18
vllt. hat ja jemand nen kommentar uebrig...
Variante 1, so:
Delphi-Quellcode:
function CreateAndFillStringList: TStringList;
begin
  Result := TStringList.Create;
  Result.Add('...');
end;

begin
  var sl: TStringList := CreateAndFillStringList;
  try
    sl.Add('more');
    ShowMessage(sl.Text);
  finally
    sl.Free;
  end;
Nicht empfohlene Lösung:
Delphi-Quellcode:
uses
  mormot.core.data;

var
  sl: TStringList;
begin
  with TAutoFree.One(sl, CreateAndFillStringList) do
    ShowMessage(sl.Text);
end;
Bis bald...
Thomas
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.051 Beiträge
 
Delphi 2009 Professional
 
#4

AW: noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 16. Okt 2023, 22:28
Man gibt normalerweise mit Funktionen keine Objekte zurück, außer es sind die Getter eines anderen Objekts, das die Instanz des zurückgegebenen Objekts verwaltet (Beispiel: die diversen Lines von TMemo und Items von TComboBox). Oder irgendeine andere Klasse kümmert sich darum, dass die irgendwann freigegeben werden (z.B. TListItems.Add).
Nur Konstruktoren geben Objekte implizit zurück die nennt man auch so. Dann weiß man: Ich muss die so benutzen, wie du es bei Button2 gemacht hast. Im allergrößten Notfall macht man das wie mytbo geschrieben hat - aber auch hier heißt die Methode irgendwas mit "Create" und da weiß ich sofort, ich muss das Ding freigeben.

Wie jaenicke schon sagte, sind übergibt man Klassen auch normalerweise nicht als var, da das Argument eigentlich nur der Zeiger ist und man die Felder und Eigenschaften von Klassen immer schreiben kann. In Delphi werden Klassen weder als var noch als const übergeben. Macht man im Normalfall bei Dingen, die ein Zeiger oder kleiner sind.

Alternativ zu Interfaces kann man Records nutzen. Nachteil: Die haben keinen Destruktor, haben keine Vererbung und können sich nicht selbst referenzieren.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 16. Okt 2023, 23:16
In Delphi werden Klassen weder als var noch als const übergeben. Macht man im Normalfall bei Dingen, die ein Zeiger oder kleiner sind.
Die Verwendung von const hat den Vorteil, dass man die Referenz nicht aus Versehen überschreiben kann. Ohne var hätte das zwar beim Aufrufer keinen Effekt, aber wenn jemand innerhalb der Methode als erstes die Stringliste neu anlegt, wäre in der übergebenen Liste hinterher nichts drin. Deshalb verwende ich const ganz gerne, auch wenn es an einer Stelle performancemäßig keinen Vorteil bringt.

Umgekehrt verwende ich es bei Interfaces teilweise nicht, wenn die Gefahr besteht, dass jemand als Parameter direkt einen Konstruktoraufruf verwendet, was mit der Referenzzählung Probleme machen kann.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#6

AW: noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 17. Okt 2023, 00:36
Du solltest aus dem var beim Parameter ein const machen, ...
Syntaktisch korrekt, aber ich würde dennoch empfehlen nicht CONS, sondern garnichts anzugeben.

* Ja, die Vairable selbst wird nicht geändert,
* aber der Inhalt schon.




Zitat:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  showmessage(getSL.Text);
end;
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  var Temp := getSL.Text;
  showmessage(Temp.Text);
  Temp.Fee;
end;

// aber eigentlich
begin
  var Temp := getSL.Text;
  try
    showmessage(Temp.Text);
  finally
    Temp.Fee;
  end;
end;
Was erstellt wird, muß auch wieder freigegeben werden, denn das "Objekt" macht es nicht von selbst.

ODER
Delphi-Quellcode:
// FSL als Variable/Feld in der übergeordneten Klasse, also hier die TForm1

function TForm1.getSL: TStringList;
begin
  if not Assigned(FSL) then
    FSL := TStringList.Create; // oder im OnCreate UND im OnDestroy sowieso das FSL.Free;
  FSL.Clear;
  FSL.Add('haha');
  FSL.Add('hehe');
  FSL.Add('hihi');
  FSL.Add('hoho');
  FSL.Add('huhu');
  Result := FSL;
end;
* hier wird Extern nicht freigegeben
* gleichzeitig, bzw. kurz nacheinander aufgerufen, muß man bedenken, dass das Result des vorherigen Aufrufs sich auch mit verändert (weil selbes Objekt)

ODER z.B. irgendwas mit einem Interface
ODER function TForm1.getSL: TArray<string>;
ODER ...
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (17. Okt 2023 um 00:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.388 Beiträge
 
Delphi 12 Athens
 
#7

AW: noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 17. Okt 2023, 06:23
Zitat:
Man gibt normalerweise mit Funktionen keine Objekte zurück
...davon habe ich reichlich. Meistens Objekte die in einer Liste verschwinden und mit der Liste freigegeben werden.
ABER: Mann sollte die Benamsung "Create...." nennen, damit man weiß, dass ein Objekte erzeugt wird, was extern freigegeben werden muß!

Geändert von haentschman (17. Okt 2023 um 07:45 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.603 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 17. Okt 2023, 08:11
Man gibt normalerweise mit Funktionen keine Objekte zurück
Solange klar ist, dass der Aufrufer sie freigeben muss, warum nicht?

Delphi-Quellcode:
sl := FunctionDieEineStringlistErzeugt(bla, blub);
try
  Verarbeite(sl);
finally
  sl.Free;
end;
funktioniert prima.

Problematisch ist eher die erzeugende Function selbst, denn was, wenn nach dem Erzeugen der Stringlist eine Exception ausgelöst wird?

Delphi-Quellcode:
function FunctionDieEineStringlistErzeugt(bla, blub: string): TStringList;
begin
  Result := TStringList.Create;
  Result.Add(bla);
  Result.Add(blub);
  raise Exception.Create('Test');
end;
Und schwupps hat man ein Leak. Natürlich ist das nie so offensichtlich wie in diesem Beispiel.

Meine Lösung dafür sieht so aus:

Delphi-Quellcode:
function FunctionDieEineStringlistErzeugt(bla, blub: string): TStringList;
begin
  Result := TStringList.Create;
  try
    Result.Add(bla);
    Result.Add(blub);
    raise Exception.Create('Test');
  except
    Result.Free;
    raise;
  end;
end;
Ich bin mir allerdings sicher, dass das irgendwie eleganter gehen müsste.

Edit: Mir ist gerade noch eine Alternative eingefallen:

Delphi-Quellcode:
function FunctionDieEineStringlistErzeugt(bla, blub: string): TStringList;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    sl.Add(bla);
    sl.Add(blub);
    raise Exception.Create('Test');
    Result := sl;
    sl := nil;
  finally
    sl.Free;
  end;
end;
Ist aber auch nicht wirklich elegant.
Thomas Mueller

Geändert von dummzeuch (17. Okt 2023 um 08:15 Uhr)
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.768 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 17. Okt 2023, 08:51

Edit: Mir ist gerade noch eine Alternative eingefallen:

Delphi-Quellcode:
function FunctionDieEineStringlistErzeugt(bla, blub: string): TStringList;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    sl.Add(bla);
    sl.Add(blub);
    raise Exception.Create('Test');
    Result := sl;
    sl := nil;
  finally
    sl.Free;
  end;
end;
Ist aber auch nicht wirklich elegant.
Zeigt da nicht result auf die gleiche Adresse wie sl,
wenn dann sl auf nil gesetz wird, ist dann nicht auch result == nil?

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.603 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: noch was zu: "Nach 20/30 starts aus der IDE speicher voll"

  Alt 17. Okt 2023, 09:11

Edit: Mir ist gerade noch eine Alternative eingefallen:

Delphi-Quellcode:
function FunctionDieEineStringlistErzeugt(bla, blub: string): TStringList;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    sl.Add(bla);
    sl.Add(blub);
    raise Exception.Create('Test');
    Result := sl;
    sl := nil;
  finally
    sl.Free;
  end;
end;
Ist aber auch nicht wirklich elegant.
Zeigt da nicht result auf die gleiche Adresse wie sl,
wenn dann sl auf nil gesetz wird, ist dann nicht auch result == nil?
Ja, aber nein:

Sowohl Result als auch sl sind Pointer auf das das Objekt. Wenn ich einen davon auf nil setze, hat das keinen Einfluss auf den anderen. Anders sähe das aus, wenn man sl nicht auf nil setzt:

Delphi-Quellcode:
function FunctionDieEineStringlistErzeugt(bla, blub: string): TStringList;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    sl.Add(bla);
    sl.Add(blub);
    raise Exception.Create('Test');
    Result := sl;
// sl := nil;
  finally
    sl.Free;
  end;
end;
Dann würde Result nach dem sl.Free auf ein freigegebenes Objekt zeigen und ein Zugriff hätte böse Folgen. Im Besten Fall eine Access Violation, im schlechtesten Fall würde zufälliger Code ausgeführt.
Thomas Mueller
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 06:21 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