Autor Beitrag
P@u1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 117



BeitragVerfasst: Mi 17.11.10 23:37 
Hi,

ich habe gerade ein Problem mit Pointern und habe den Verdacht, dass Delphi automatisch Objekte freigibt (ich war immer davon ausgegangen, dass Objekte nur freigegeben werden, wenn man das selbst explizit macht).

Zur Erklärung: TBitMapEx ist eine Erweiterung von TBitMap und hat z.B. die Methode GetScreenShot, deren Funktion offensichtlich sein sollte.

Ich habe eine FormCreate-Methode die so aussieht:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.FormCreate(Sender: TObject);
var
  Pbmp : ^TBitMapEx;
  bmp : TBitMapEx;
begin
  List := TList.Create;
  bmp := TBitMapEx.Create;
  Pbmp := @bmp;
  Pbmp^.GetScreenShot;
  List.Add(Pbmp);
  Image1.Picture.Bitmap := TBitMapEx(List.Items[0]^);
end;


Das ganze funktioniert auch.
Aber wenn ich jetzt im Button1Click folgendes mache:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Image1.Picture.Bitmap := TBitMapEx(List.Items[0]^);
end;

Gibt es eine Zugriffsverletzung!
Es wurde also das mit
ausblenden Delphi-Quelltext
1:
  bmp := TBitMapEx.Create;					

So wie ich das sehe automatisch freigegeben.

Wenn ich bmp global definiere, passiert das nicht.
Wieso wird das denn freigegben, es ist doch ein Objekt!
Und wie kann ich das Verhindern?
Ich möchte das Objekt ja später noch über die Liste ansprechen können.

Dann hab ich noch was mit dem Befehl new versucht:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.FormCreate(Sender: TObject);
var
  Pbmp : ^TBitMapEx;
begin
  new(Pbmp);
  Pbmp^.GetScreenShot;
end;

Gibt auch einen Error (Zugriffsverletzung).
Erstellt das new nicht auch eine Instanz, oder wie funktioniert das?

Ich bin jetzt gerade extremst verwirrt und hoffe auf Hilfe!
Dude566
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: Do 18.11.10 00:15 
Ich nehme mal an, dass nicht das Objekt gelöscht wird, sonder lediglich der Verweis (Instanzvariable), da diese nur lokal in der Funktion deklariert ist. ;)

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Do 18.11.10 00:28 
Du erzeugst das Objekt, die Referenz liegt bei Dir auf dem Stack, interessanterweise übergibst Du dann noch eine Zeiger auf diese Stackvariable an die Liste.
In der Liste sind dann Zeiger auf den Stack, welcher sich permanent ändert ;-).

Warum nicht einfach
ausblenden Delphi-Quelltext
1:
List.add(TBitmapEx.Create);					

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Dude566
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: Do 18.11.10 00:32 
Ich habe sowieso nicht verstanden, warum du den Pointer in FormCreate brauchst.

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 18.11.10 06:58 
user profile iconP@u1 hat folgendes geschrieben Zum zitierten Posting springen:
Gibt auch einen Error (Zugriffsverletzung).
Erstellt das new nicht auch eine Instanz, oder wie funktioniert das?
Nein, mit New kannst du Speicher für einen Pointer reservieren. Zum Beispiel für einen Pointer auf einen Record, dann wird so viel Speicher reserviert wie der Record groß ist.

So, du reservierst also 4 Byte (unter 32-Bit), denn so groß ist das Ziel deines Pointers. Denn das Ziel deines Pointers ist nur wieder ein Pointer auf die eigentliche Bitmap.

Nebenbei rate ich dir für Objekte zu TObjectList. Die kannst du da direkt als Objekte hineinpacken. (ab Delphi 2009 sogar direkt typisiert, vorher nur manuell). Die gibt dann auf Wunsch beim Löschen eines Objekts aus der Liste oder beim Zerstören der Liste die passenden Objekte automatisch frei.
P@u1 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 117



BeitragVerfasst: Do 18.11.10 10:45 
Das mit der Objektlist ist ein guter Tipp, danke.
Nur ich habs nicht hinbekommen, dass typisiert zu verwenden, ich habs so versucht:
ausblenden Delphi-Quelltext
1:
ObjList : TObjectList<TBitMapEx>;					


Oder geht das bei Delphi irgendwie anders?

Und falls ichs untypisiert verwende, dann hat das zur Folge, dass ich, wenn ich ein Element benutzen will es erst auf BitMapEx casten muss, richtig?

Und dann noch mal zu den Pointern, ist das bei Delphi so, dass wenn ich folgendes mache:
ausblenden Delphi-Quelltext
1:
bmp := TBitMapEx.Create;					

in bmp automatisch nur ein Pointer gespeichert wird und ich deswegen einen Pointer auf einen Pointer hatte, der nur lokal definiert war und deswegen danach nicht mehr erreichbar war, oder hab ich was falsch verstanden?
Das heißt, dass Konzept davon ist gleich oder sehr ähnlich zu Java?

Das würde dann ja heißen, dass ich bmp direkt in die List reinpacken kann ohne @ zu benutzen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 18.11.10 11:29 
user profile iconP@u1 hat folgendes geschrieben Zum zitierten Posting springen:
Nur ich habs nicht hinbekommen, dass typisiert zu verwenden, ich habs so versucht:
Welche Delphiversion? Und was ist passiert?

user profile iconP@u1 hat folgendes geschrieben Zum zitierten Posting springen:
Und falls ichs untypisiert verwende, dann hat das zur Folge, dass ich, wenn ich ein Element benutzen will es erst auf BitMapEx casten muss, richtig?
Ja

user profile iconP@u1 hat folgendes geschrieben Zum zitierten Posting springen:
in bmp automatisch nur ein Pointer gespeichert wird und ich deswegen einen Pointer auf einen Pointer hatte, der nur lokal definiert war und deswegen danach nicht mehr erreichbar war, oder hab ich was falsch verstanden?
Nein, das hast du richtig verstanden.

user profile iconP@u1 hat folgendes geschrieben Zum zitierten Posting springen:
Das heißt, dass Konzept davon ist gleich oder sehr ähnlich zu Java?
Bei Objekten gilt das meistens, auch in anderen Sprachen. Bei Records und sowas natürlich nicht.

user profile iconP@u1 hat folgendes geschrieben Zum zitierten Posting springen:
Das würde dann ja heißen, dass ich bmp direkt in die List reinpacken kann ohne @ zu benutzen.
Ja.
P@u1 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 117



BeitragVerfasst: Do 18.11.10 16:30 
Vielen Dank für die Hilfe!

Ich verwende Delphi 2010.
Allein beim Deklarieren passiert schon folgendes:
ausblenden Delphi-Quelltext
1:
2:
3:
var
  Form1: TForm1;
  ObjList : TObjectList<TBitMapEx>;


[DCC Fehler] Unit1.pas(20): E2003 Undeklarierter Bezeichner: 'TObjectList<>'
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Do 18.11.10 16:32 
Hey,

such mal in der Delphi Hilfe nach TObjectList, da steht welche Units du einbinden musst (hab sie jetzt nicht im Kopf).

€: ich weiß auch nicht ob man die TObjectList typisieren kann, kann aber dein das es bei D2010 schon funktioniert, ich arbeite noch mit D7.


MfG Bergmann

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
P@u1 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 117



BeitragVerfasst: Do 18.11.10 16:41 
untypisiert reicht es, wenn ich Contnrs einbinde.
Typisiert funktioniert damit nicht, aber ich guck jez mal eben in der Hilfe.
Edit: Mir fällt gerade auf, dass ich vergessen hab, die Hilfe zu installieren bisher... ich guck mal kurz im Internet ob ich was brauchbares finde.
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Do 18.11.10 16:44 
nimm Generics.Collections in die uses auf....

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
P@u1 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 117



BeitragVerfasst: Do 18.11.10 16:46 
Habs gerade gefunden, aber trotzdem vielen Dank!

Funktioniert jetzt alles wunderbar und ich hab die Sachen jetzt auch verstanden mit dem doppeltem Pointer und so, was ich falsch gemacht habe. Ich markier also mal als erledigt, vielen Dank an alle, die mir geholfen haben.