AGB  ·  Datenschutz  ·  Impressum  







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

Lazarus, Problem mit TMemoryStream

Ein Thema von Gutelo · begonnen am 31. Aug 2014 · letzter Beitrag vom 1. Sep 2014
Antwort Antwort
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#1

AW: Lazarus, Problem mit TMemoryStream

  Alt 1. Sep 2014, 00:57
Vielleicht noch ein Stück Hintergrundinfo: In der Variable steht ein Pointer auf ein Stück Speicher. Welchen wir OOPler gerne hochtrabend "Referenz" nennen, aber technisch ist es eben nur ein Pointer. Zumindest in den meisten nativ kompilierenden Umgebungen, wie Delphi und Lazarus für Windows.

An diesem Stück Speicher werden durch den Konstruktor eines Objektes ein Haufen Daten geschrieben die die eigentliche Instanz beschreiben, und der benutzte Speicher als "in Verwendung" markiert.

Das einzige was .Free() macht: Es nimmt die Markierung "in Verwendung" für das Stück Speicher wieder weg. Die Referenz, also unsere Variable, also den Pointer, lässt es unberührt. Es lässt sogar die Daten an diesem Stück Speicher unberührt! Heisst: Selbst nach einem .Free() kann dort noch die völlig intakte Instanz stehen! Eben so lange, bis der Speichermanager wieder für etwas anderes ein Stück Speicher braucht, und dieses als "frei" markierte Stück wird auserwählt UND danach auch wirklich mit anderen Daten beschrieben.

Folge: Selbst nach einem .Free() könnten selbst Low-Level Methoden, die nach einer Instanz-Artigen Struktur an der Stelle wo der Pointer hin zeigt suchen, können "false positive" Ergebnisse liefern. Auch eine Prüfung, ob der Speicher auf den gezeigt wird noch in Benutzung ist bringt keine gesicherten Ergebnisse, weil er könnte ja durchaus in der Zwischenzeit durch andere Instanzen oder Elemente belegt worden und somit in Benutzung sein - aber nicht eine gültige Instanz zu deinem erwarteten Objekt beinhalten.

Lösung: Du musst dir selber merken hinter welcher Referenz noch eine gültige Instanz liegt. Der einfachte Weg dafür ist der oben gezeigte: Die Referenz auf nil setzen.

Lustig wird sowas, wenn es mehrere Referenzen auf ein und die selbe Instanz geben könnte. Nil-Setzen einer Referenz macht dies natürlich nicht automatisch für alle möglichen anderen. Wenn so etwas vorkommt, gibt es diverse andere Strategien. Interfaces und Smart-Pointer sind zum Beispiel welche, und welche sich nachher eignet ist (wie immer) hoch individuell von der Aufgabe abhängig. (In deinem Fall reicht aber nil setzen alle Male aus.)

Dies betrifft praktisch alle Compiler die nativen Code erzeugen. Bei Sprachen wie Java oder Script-Sprachen kann es auch so sein, hier hätte man aber potenziell andere Möglichkeiten. (Die sicherlich von diversen auch genutzt werden, aber da habe ich wenig Detailerfahrung.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Gutelo

Registriert seit: 29. Sep 2013
152 Beiträge
 
#2

AW: Lazarus, Problem mit TMemoryStream

  Alt 1. Sep 2014, 14:09
Danke fuer die Antworten.

Jetzt ist es mir klar geworden.

Im internet steht viel falsches darueber. Z.b. dass free automatisch auf nil setzt und dass viele Assigned(object) verwenden...

Gutelo
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#3

AW: Lazarus, Problem mit TMemoryStream

  Alt 1. Sep 2014, 17:12
Achtung: Es gibt in Delphi die Funktion FreeAndNil(MyObject). Die tut das!! Die Funktion sieht im Grunde so aus:
Delphi-Quellcode:
procedure FreeAndNil(var aObject: TObject);
var
  tmp: TObject;
begin
  tmp := aObject;
  if tmp <> nil then
    tmp.Free;
  aObject := nil;
end;
Wenn man etwas so frei gibt, dann kann man mit Assigned(MyObject) genau so arbeiten. Das geht aber nicht, wenn man nur MyObject.Free; benutzt. Schau nochmal genau nach.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Gutelo

Registriert seit: 29. Sep 2013
152 Beiträge
 
#4

AW: Lazarus, Problem mit TMemoryStream

  Alt 1. Sep 2014, 18:58
Danke Medium,

so hab ich es auch verstanden.

Gruss

Gutelo
  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
 
#5

AW: Lazarus, Problem mit TMemoryStream

  Alt 1. Sep 2014, 17:30
Im internet steht viel falsches darueber. Z.b. dass free automatisch auf nil setzt und dass viele Assigned(object) verwenden...
Hast du da mal eine belastbare Quelle?
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
Benutzerbild von himitsu
himitsu

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

AW: Lazarus, Problem mit TMemoryStream

  Alt 1. Sep 2014, 17:51
if Assigned(object) then verwenden wirklich Viele, auch wenn es im Grunde genommen nichts Anderes macht, als ein if object <> nil then .

Gut, ich finde Assigned verständlicher, also dessen Funktion anhand des Namens, und bei sowas wie Methodenzeigern macht Assigned noch mehr, denn diese Zeiger bestehen ja aus zwei Zeigern, welche man sonst einzeln prüfen müsste.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort


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:32 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