AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

record fillchar Speicherleck

Ein Thema von baumina · begonnen am 17. Apr 2014 · letzter Beitrag vom 19. Apr 2014
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von baumina
baumina

Registriert seit: 5. Mai 2008
Ort: Oberschwaben
1.275 Beiträge
 
Delphi 11 Alexandria
 
#1

record fillchar Speicherleck

  Alt 17. Apr 2014, 09:09
Speicherverwaltung war noch nie meine Stärke. Wie vermeide ich sinnvoll folgendes Speicherleck?

Delphi-Quellcode:
program Project2;

uses
  Forms;

{$R *.res}

type
  MyRecord = record
    S1 : String;
    S2 : String;
  end;

var
  GlobVar : MyRecord;

begin
  ReportMemoryLeaksOnShutdown := True;
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  fillchar(GlobVar, SizeOf(GlobVar), 0);
  Globvar.S1 := 'testString';
  fillchar(GlobVar, SizeOf(GlobVar), 0); <-- ab jetzt Speicherleck
  Application.Run;
end.
Hintergrund : Ich hatte mich für einen globalen Record entschieden, da dieser alle wichtigen Daten meines aktuell gewählten Mantanten enthält, auf die ich ständig zugreifen muss. Fillchar deswegen, um bei einem Mandantenwechsel erst alle Inhalte zu leeren.
Hinter dir gehts abwärts und vor dir steil bergauf ! (Wolfgang Ambros)
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.201 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: record fillchar Speicherleck

  Alt 17. Apr 2014, 09:14
Mit Fillchar zerstörst du die Verwaltungsinformationen der Strings (Referenzzählung etc.) Also ganz böser Fehler!

Du solltest nur

Delphi-Quellcode:
GlobVar.S1 := ''
GlobVar.S2 := ''
machen
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Nersgatt
Nersgatt

Registriert seit: 12. Sep 2008
Ort: Emlichheim
693 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

AW: record fillchar Speicherleck

  Alt 17. Apr 2014, 09:21
Ich würde dem Record dann eine Procedure verpassen, um ihn zu leeren:

Delphi-Quellcode:
MyRecord = record
    S1 : String;
    S2 : String;
    procedure Clear;
  end;
Somit könntest Du dann irgendwo einfach GlobVar.Clear aufrufen.
Jens
  Mit Zitat antworten Zitat
Benutzerbild von baumina
baumina

Registriert seit: 5. Mai 2008
Ort: Oberschwaben
1.275 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: record fillchar Speicherleck

  Alt 17. Apr 2014, 09:32
Klasse, danke Euch beiden!!!!
Hinter dir gehts abwärts und vor dir steil bergauf ! (Wolfgang Ambros)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.027 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#5

AW: record fillchar Speicherleck

  Alt 17. Apr 2014, 09:39
Oder GlobVar := Default(MyRecord); Abgesehen davon werden globale Variablen sowieso initialisiert, d.h. es besteht keine Veranlassung in deinem Beispiel, das von Hand zu tun (der Aufruf vor dem Zuweisen des strings).
Anders sähe es natürlich bei einer lokalen Variable aus!
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (17. Apr 2014 um 09:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von baumina
baumina

Registriert seit: 5. Mai 2008
Ort: Oberschwaben
1.275 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: record fillchar Speicherleck

  Alt 17. Apr 2014, 10:03
Default Toller Befehl! Kenn ich nicht, finde auch keine Hilfe dazu, aber funktioniert, mal schauen ob ich mich daran in zwei Jahren noch erinnern kann.
Hinter dir gehts abwärts und vor dir steil bergauf ! (Wolfgang Ambros)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: record fillchar Speicherleck

  Alt 17. Apr 2014, 10:05
Und Delphi-Referenz durchsuchenFinalize da, wo es Default(...) noch nicht gab.

Aber das ganze in die Clear, Metode auszulagen kann nicht schaden. (wie dann darin geleert wird, ist egal, Hauptsache es wird "richtig" gemacht)



FillChar setzt "blind" alles auf 0, wobei natürlich mutwillig die automatisch verwalteten Referenzen geschrottet werden.
$2B or not $2B

Geändert von himitsu (17. Apr 2014 um 10:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#8

AW: record fillchar Speicherleck

  Alt 17. Apr 2014, 11:00
Und Delphi-Referenz durchsuchenFinalize da, wo es Default(...) noch nicht gab.
Gute Idee. Aber, ich hab gerade in der Hilfe gestöbert, was ist mit solchen Records:
Delphi-Quellcode:
record
  Name : string;
  Vorname : string;
  Geburtstag : tdatetime;
  Kenner : array [0..8] of char;
  GenommeneUrlaubstage : byte;
end;
werden Geburtstag,Kenner und GenommeneUrlaubstage genullt oder nicht?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: record fillchar Speicherleck

  Alt 17. Apr 2014, 12:57
Kommt jetzt drauf an, wie es implementiert wurde.

Bei "Optimaler Laufzeigt" würden diese nicht behandelt,
aber es spricht nichts dagegen nach dem Finalize nochmal ein FillChar/ZeroMemory drüber laufen zu lassen. (nil bleibt dann ja 0)

Interfaces, dynamische Arrays (Kenner ist statisch), LongStrings (also AnsiString, WideString und UnicodeString) und Variants würde man sonst schrotten und Speicherlecks erschaffen.
Wobei ShortString (und die Typen String[x]) aber ein statisches Array ist.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.027 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#10

AW: record fillchar Speicherleck

  Alt 17. Apr 2014, 14:14
Gute Idee. Aber, ich hab gerade in der Hilfe gestöbert, was ist mit solchen Records:
Delphi-Quellcode:
record
  Name : string;
  Vorname : string;
  Geburtstag : tdatetime;
  Kenner : array [0..8] of char;
  GenommeneUrlaubstage : byte;
end;
werden Geburtstag,Kenner und GenommeneUrlaubstage genullt oder nicht?
Ja, Default macht nix anderes, als zusätzlich noch FinalizeRecord aufzurufen, wenn managed Fields vorhanden sind.

Hier mal der Auszug aus dem assembler code:
Code:
006494C5 8D45D0           lea eax,[ebp-$30]
006494C8 8B15E8936400     mov edx,[$006493e8]
006494CE E809EEDBFF      call @FinalizeRecord
006494D3 8BF8             mov edi,eax
006494D5 33C0             xor eax,eax
006494D7 B90A000000       mov ecx,$0000000a
006494DC F3AB            rep stosd
Die Funktion gibts seit Generics, damit man in generischem Code ein leeres Element von irgendeinem Typ erzeugen kann (Default(T)).
Lässt sich aber ebend auch prima in nicht generischem Code benutzen.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (17. Apr 2014 um 14:23 Uhr)
  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 07:27 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