Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Speicher freigeben oder nicht??


infomio - Di 25.02.03 09:18
Titel: Speicher freigeben oder nicht??
Hallo, ich bin ziemlicher Programmieranfänger und habe eine brennende Frage:

Wenn ich unter Pascal im private oder public - Bereich Variablen deklariere und die dann natürlich auch benutze, muß ich dann irgendwann den Speicher wieder freigeben, oder macht das Delphi automatisch. Ich mach nämlich grad ne C++ Schulung und der Tutor behauptet, man müsse sich immer um den Speicher kümmern, weil sonst der ganze Speicher im Stack und nicht im Heap reserviert wird???
Und in den wie lerne ich Delphi Büchern wird sowas auch nicht angesprochen???

Ich brauche Fakten zu diesem Thema, weil ich wissen muß, ob ich so falsch oder richtig programmiere...

Danköööö !!!


Anonymous - Di 25.02.03 10:06

Hängt von der Variable ab. Bei normalen Variablen (z.B. Integer, Real, String, ...) brauchst du nichts freigeben. Da kümmert sich Delphi drum. Anders sieht es mit Objektvariablen aus. Zwar sind die Variablen selbst nur Zeiger auf das Objekt, aber du mußt das Objekt freigeben.

Beispiel:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    sl.Add('popov4ever');
  finally
    sl.Free;
  end;
end;


Mit Free gibst du das Objekt frei und seinen Speicher. Ohne Free bleibt das Objekt auch nach Ende des Programms im Speicher.


infomio - Di 25.02.03 10:38

also nochmal zum mitschreiben:

es gibt normale Variablen, die sich aber auch nicht im Stack befinden, dort sind lediglich die Zeiger. Richtig? und Delphi kümmert sich da automatisch ums free.
Dann gibts noch Object-Variablen. Die setzt man selber in den Heap und muss sich auch selber um den Free kümmern??? Hab ich das richtig verstanden ???
Und warum zum Geier kümmert sich Delphi nicht auch um diese automatisch im Jahre 2003 ??? Was wäre denn daran so falsch???
Oder kennt jemand den Grund???


AndyB - Di 25.02.03 10:48

infomio hat folgendes geschrieben:
Oder kennt jemand den Grund???

Woher soll Delphi denn wissen, wann du die Instanz nicht mehr benötigt? Es gilt auch: Was du selbst erstellt hast, muss du auch selbst wieder freigeben.


Zitat:
Und warum zum Geier kümmert sich Delphi nicht auch um diese automatisch im Jahre 2003 ???

Das kann Delphi schon. Du musst dann nur deine Programmierung der Klassen auf Interfaces auslegen, was aber bei herkömmlichen Klassen nur zu mehr Schreibarbeit führt (Copy&Paste sei dank).


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
ITest = interface
  procedure SetMe(i: Integer);
  function GetMe: Integer;
  property Me: Integer read GetMe write SetMe;
end;

TTest = class(TInterfacedObject, ITest)
private
  FValue: Integer;
public
  procedure SetMe(i: Integer);
  function GetMe: Integer;

  property Me: Integer read GetMe write SetMe;
end;

procedure TTest.SetMe(i: Integer);
begin
  FValue :=  i;
end;
function TTest.GetMe: Integer;
begin
  Result := i;
end;


procedure TForm1.Button1Click(Sender: TObject)
var Test: ITest;
begin
  Test := TTest.Create;
  Test.Me := 100;
  ShowMessage(IntToStr(Test.Me));
end;


Anonymous - Di 25.02.03 11:08

Du machst C++ Schulung? Du willst mit Delphi arbeiten? Dann wergiß bei Delphi das was du in C++ machen mußt. Du denkst viel zu kompliziert. Es ist nicht falsch zu wissen was im Hintergrund passiert, aber diese Arbeit (bzw. Gedanken) brauchst du dir bei Delphi über die Variablen nicht machen. Du brauchst einen Integer? Dann einfach var i: Integer;. Seit anbegin der Zeit (ein wenig weit ausgeholt) kümmern sich die höheren Programmiersprachen um die Verwaltung der Variablen. Es gibt sogar Sprachen da brauchst du selbst keine Variablen zu deklarieren. Warum soll also etwas in Büchern besprochen werden was dich garnicht zu interresieren Braucht. Pech für dich, daß du mit ein Sprache anfängst bei der man sich auch um den kleinsten Schei* selbst kümmern muß. Dafür hat aber C++ andere Vorteile.


Christian S. - Di 25.02.03 12:04

@AndyB:
Zitat:
Woher soll Delphi denn wissen, wann du die Instanz nicht mehr benötigt?
Delphi könnte es beispielsweise so machen, dass sobald keine Referenz mehr auf das Objekt besteht, es vernichtet wird. So macht es die Garbage Collection bei Java.

Popov hat folgendes geschrieben:
Du brauchst einen Integer? Dann einfach var i: Integer;
Ähm, ist das bei C++ denn anders. Habe nur mal kurz reingeschaut, aber soweit ich weiß, geht es doch dort noch einfacher, weil Du keinen Deklarationsteil brauchst. Oder? Und da Integer zu den primitiven Datentypen gehört, muss ich den auch bei C++ nicht wieder wegräumen.

MfG,
Peter


Klabautermann - Di 25.02.03 12:13

Peter Lustig hat folgendes geschrieben:
Popov hat folgendes geschrieben:
Du brauchst einen Integer? Dann einfach var i: Integer;
Ähm, ist das bei C++ denn anders. Habe nur mal kurz reingeschaut, aber soweit ich weiß, geht es doch dort noch einfacher, weil Du keinen Deklarationsteil brauchst. Oder? Und da Integer zu den primitiven Datentypen gehört, muss ich den auch bei C++ nicht wieder wegräumen.

Das sehe ich änlich. Ein

Quelltext
1:
int i;                    

finde ich nicht wirklich kompliziert. Durch die Selbstaufrufenden Konstruktoren und Destruktoren in C++ ist der umgang mit Objekten eigenlich auch einfacher, denn man kann sie verwenden wie "normale" Variablen.

Gruß
Klabautermann


Christian S. - Di 25.02.03 12:18

Zitat:
Durch die Selbstaufrufenden Konstruktoren und Destruktoren in C++ ist der umgang mit Objekten eigenlich auch einfacher, denn man kann sie verwenden wie "normale" Variablen.

Soweit war ich in C++ noch nicht. Ich kenne nur Java etwas besser, und da musst Du neue Objekte mit "new" erstellen. Geht das bei C++ anders?

MfG,
Peter


Klabautermann - Di 25.02.03 12:39

Peter Lustig hat folgendes geschrieben:
Soweit war ich in C++ noch nicht. Ich kenne nur Java etwas besser, und da musst Du neue Objekte mit "new" erstellen. Geht das bei C++ anders?


Quelltext
1:
2:
  tMyClass MyObject;
  MyObject.MachWas();

Du kannst Objekte genauso deklarieren wie Variablen. Bei der Deklaration wird automatisch der Konstruktor aufgerufen. Der destruktor wird an den stellen (automatisch) aufgerufen an der Variablen auch freigegeben würden. also z.B. beim verlassen der funktion.

Natürlich kann man Objekte auch dynamisch erzeugen. Wenn ich mich recht entsinne (habe ich ewig nicht gemacht) geschar die wie bei dynamischen Variablen mit new und muss dann natürlich auch mit delete wieder freigegeben werden.

Gruß
Klabautermann


Anonymous - Di 25.02.03 12:43

Popov hat folgendes geschrieben:
... Du brauchst einen Integer? Dann einfach var i: Integer; ... Pech für dich, daß du mit ein Sprache anfängst bei der man sich auch um den kleinsten Schei* selbst kümmern muß. ...


Das mit dem kleinsten Schei* bezog sich jetzt nicht direkt auf die Deklaration des Integers, auch wenn sich das so angehört hat. Das meinte ich allgemein.


Christian S. - Di 25.02.03 12:48

@Klabautermann:

Quelltext
1:
TMyClass MyObject                    

Ja, das gibt es bei Java auch, aber wenn Du eine neue Instanz erstellen willst, musst Du es (in Java) so machen:

Quelltext
1:
TMyClass MyObject = New TMyClass                    

Meine ich zumindest, habe schon länger nicht mehr in Java programmiert. Delete entfällt bei Java völlig, das passiert automatisch, wenn keine Referenz mehr auf das Objekt vorhanden ist.

MfG,
Peter


infomio - Di 25.02.03 12:59

Laaaaangsam, Leute!!! :!:

Ich dachte Pascal wäre eine procedurale Sprache, warum muß man sie dann mit OOP vergewaltigen??? Ich habe nämlich noch nicht den großen Vorteil von Objekten gegenüber Proceduren und Funktionen verstanden!!!


infomio - Di 25.02.03 13:01

PS: woher soll Delphi wissen, wann ich die Instanz nicht mehr brauche - na wenn ich die Applikation beende halt, ist doch easy!


Delete - Di 25.02.03 13:46

Delphi heißt die IDE. Borland die Firma die sie entwickelt und Object Pascal die Programmiersprache. Und wie der Name schon sagt gehört Object Pascal zur Famile der OOP-Sprachen und das ist auch gut so. :wink:

Da bist du wohl einem Mißverständnis aufgesessen. :roll:


Klabautermann - Di 25.02.03 14:14

Hallo,
Luckie hat folgendes geschrieben:
[...]und Object Pascal die Programmiersprache.[...]

seit Delphi 7/ Kylix 3 heißt die Sprache Delphi-Language. Das gefällt mir zwar auch nicht, ist aber leider so :(.

Alles andere ist aber korreckt ;).

@infomio: Ich habe mich anfangs auch schwer getan mit den Objekten, weil ich deren sinn nicht erkannte. Ich habe mich dann um dahinter zu kommen dazu gezwungen sie zu verwenden. Heute würde ich nicht mehr drauf verzichten wollen. Sie bringen insbesondere vorteile in punkto übersich, organisation, und Versionskompatibilität (durch Polymorphie).
Man muss es aber tatsächlich intensiev ausprobiert haben um es zu erkennen - zumindest war das bei mir so.
Daher solltest du dich drauf einlassen.

Gruß
Klabautermann


Delete - Di 25.02.03 14:44

War bei mir auch so. Und wenn man seine Klassen, Objekte gut entwirft, dann geht die Porgrammierung fast von alleine. :P


infomio - Di 25.02.03 17:17

Also erstma herzlichen Dank für die vielen Antworten, auch wenn ich nicht alles kapiert habe...!!! :D

Aber eine Frage bleibt mir immer noch ungeklärt:

Warum im Jahre 2003 Speicherbereiche, auch wenn ich sie selber zugewiesen habe, nach Beenden der Applikation im Speicher zurückbleiben. Ich meine, so umständlich hat man schon vor 20 Jahren in Assembler programmieren müssen, wo ist der Fortschritt ???
Also warum kann man den Speicher nicht automatisch wieder freigeben???
WARUM ???


AndyB - Di 25.02.03 17:52

infomio hat folgendes geschrieben:
Warum im Jahre 2003 Speicherbereiche, auch wenn ich sie selber zugewiesen habe, nach Beenden der Applikation im Speicher zurückbleiben. [...] Also warum kann man den Speicher nicht automatisch wieder freigeben???

Die Aussage von oben ist falsch. Windows gibt den Speicher sehr wohl beim Programmende frei. Das heißt aber nicht, dass du nun schlampig programmieren darft.


Anonymous - Di 25.02.03 18:32

Ich würde dir empfehlen dir ein schlaues Buch zu besorgen und dir die nötigen Infos anzulesen. Du stellst durchaus schlaue Fragen, vermischt aber alles andere derart durcheinander, daß man das Gefühl hat, daß du am besten wieder bei 1 mal 1 anfangen solltest.

Aus dem was ich durchgelesen habe hast du null Ahnung was Objekte sind, jamerst aber, daß man sie freigeben muß. Ist das jetzt Panik? Ich gebe zu, daß ich mir die Frage nie stellte. Ok, ein oder zwei mal. Allerdings ist Pascal eine alte Sprache. Diese Sprache wurde immer weiter Erweitert. Das was heute OOP ist, fing auch mal klein in TP an. Es spielt somit keine Rolle ob wir jetzt das Jahr 2003 haben. Auch wenn Delphi 10000 Funktionen hat, so ist es immer noch Pascal. So wie die Objekte gehandhabt werden, sind sie durchaus immer noch mit Pascal vereinbar. Im grunde genommen ist doch die Objektvariable nur ein Zeiger auf eine Adresse. Es ist nicht das Objekt. Die Objekte sind somit, so verstehe ich es, kein Bestandteil von Pascal. Pascal kann mit Objekten arbeiten, ist aber keine Objektsprache. Pascal ist somit nur mit einem Trick OOP. Wenn man jetzt also automatisch beim beenden auch die Objekte freigeben würde, dann würde man etwas machen was mit Pascal nicht vereinbar wäre. Man hätte dann eine Pascalähnliche Sprache, aber nicht Pascal. Deshalb muß man sich um die Freigabe selbst kümmern. Diese Probleme haben "richtige" Objektorientierte Sprachen nicht. Sie müssen nicht kompatibel bleiben.

Allerdings kann sein, daß das alles auch nur Blödsinn ist. Hab davon sowieso keine Ahnung.


Anonymous - Di 25.02.03 19:27

AndyB hat folgendes geschrieben:
... Windows gibt den Speicher sehr wohl beim Programmende frei. Das heißt aber nicht, dass du nun schlampig programmieren darft.


Naja, ob das stimmt. Ich hab mich mal zu sehr auf den Autovervollständiger verlassen und hab nach Bmp.Fr einfach auf Enter geklickt. Ich hab nicht nachgedacht und gemeint, daß Free vervollständigt wird. Nur hat Autovervollständiger FreeImage ausgegeben. Ich hab mich die ganze Zeit nur noch gewundert wieso plötzlich der Speicher so schnell voll wurde. Da ich mir sicher war, daß alle Objekte freigegeben habe, hab ich nichts überprüft. Ich hab mich nur gewundert. Irgendwann hab ich doch alles kontrolliert.


AndyB - Di 25.02.03 19:48

Ein Bitmap ist eine Systemresource und die sind bei Win9x/ME an einer einzigen Stelle registriert. Wenn man dieses vergisst gehen die GDI Resourcen aus. Diese werden auch nicht beim Programmende freigegeben.
Unter Windows NT/2000/XP werden alle vom Programm belegten Resourcen (GDI und Heap) auf jeden Fall bei Programmende freigegeben.


Anonymous - Di 25.02.03 20:12

Das mit dem Programmender wäre noch akzeptapel gewesen. Bei dem Problem handelte sich um eine Prozedur in der das Bitmap Objekt erstellt und wieder freigegeben wurde. Die Prozedur wurde mehrmals pro Minute aufgerufen.


infomio - Mi 26.02.03 09:09

ich hab halt nur den Eindruck, daß viele Objekte erstellt werden, deren Sinn durchaus kritisch hinterfragt werden kann...ne einfache Funktion tuts da meist auch!!!


Also Danke an alle, ich werd mich mal in OOP wagen und wehe es macht keinen ersichtlichen Sinn !!! Späßle...


infomio - Mi 26.02.03 09:13

Popov hat folgendes geschrieben:
... Pascal kann mit Objekten arbeiten, ist aber keine Objektsprache. Pascal ist somit nur mit einem Trick OOP. Wenn man jetzt also automatisch beim beenden auch die Objekte freigeben würde, dann würde man etwas machen was mit Pascal nicht vereinbar wäre.


Und genau den Satz habe ich nicht begriffen!


Delete - Mi 26.02.03 12:36

AndyB hat folgendes geschrieben:

Unter Windows NT/2000/XP werden alle vom Programm belegten Resourcen (GDI und Heap) auf jeden Fall bei Programmende freigegeben.

Das gilt auch für Windows9x so viel ich weiß.

Es verhält sich so und damit erklärt sich auch Popovs Problem: Wärend des Programmablaufes muß ich schon meine selbst erstellten Objekte und belegten Ressourcen wieder freigeben, weil ich sonst den Speicherbereich meines Programmes zu mülle. Klar. Wenn ich in einem Timer-Ereignis jedes mal ein Bitmap im Speicher anlege und den Speicher nicht mehr freigeben ist irgendwann das Ende der Fahnenstange erreicht.
Aber wenn das Programm beendet wird, dann wird von Windows auch der gesamte belegte Speicher wirder freigegeben und ist danach wieder von Windows nutzbar. Auch wenn mein Programm nicht selbst alles freigibt.

(Nach zu lesen im Jeffrey Richter "Windows Programmierung für Experten".)


Anonymous - Mi 26.02.03 13:24

infomio hat folgendes geschrieben:
ich hab halt nur den Eindruck, daß viele Objekte erstellt werden, deren Sinn durchaus kritisch hinterfragt werden kann...ne einfache Funktion tuts da meist auch!!!


Gib mal ein Beispiel. Welche Objekt erscheinen dir wenig sinnvoll als Objekte. Gib mal zwei oder drei Beispiele. Vieleicht können wir anhand der Beispiele den Sinn ein wenig vedeutlichen.

Ich hab mal eine Unit geschrieben in der ich das Arbeiten mit Ini's sehr vereinfacht habe. Der Programmierer braucht sich somit nicht um Objekte kümmern, sondern kann Iniwerte per einfache Funktion schreiben.

Das ganze erleichtert die Arbeit ungemein. Allerdings nicht wenn ich viele Ini Anweisungen am Stück habe. Dann ist das Arbeiten mit meinen Funktionen komplizierte, weil ich z.B. bei jeder Funktion den Inipfad angeben muß. Wenn ich mit der TIniFile arbeite, dann mache ich es nur ein mal. Ansonsten fällen mir keine Klassen ein die ich gerne per Unit vereinfachen würde.


infomio hat folgendes geschrieben:
Also Danke an alle, ich werd mich mal in OOP wagen und wehe es macht keinen ersichtlichen Sinn !!! Späßle...


Bedenke einfach, es gibt zig tausend Programmierer. Wenn Arbeiten mit Objekten Blödsinn wäre, dann hätte sich das ganze nicht durchgesetzt.