Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi vergisst die Werte der Eigenschaften meiner Klasse (https://www.delphipraxis.net/162512-delphi-vergisst-die-werte-der-eigenschaften-meiner-klasse.html)

Andre93 25. Aug 2011 18:14

Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
hey...
also ich habe folgendes problem und ich würde mich wirklich sehr freuen wenn mir irgendjemand hier weiter helfen kann:
ich habe eine Klasse TData erstellt.
Diese hat die Eigenschaften :
_Data : Pointer;
_MaxSize, _RealSize, _DataType : Integer;
und die Prozeduren :
procedure Init(MaxSize, DataType : Integer);
procedure Input(Data : Pointer; RealSize : Integer);
procedure Output(var Data : Pointer);

Die Prozedur Init soll nach dem create von TData den Eigenschaften _MaxSize, und _DataType einen Wert zuweisen.
Mit der Prozedur Input kann ich dann ein "Datenpaket" ,das durch den Pointer _Data representiert wird dazu packen und in der Eigenschaft _RealSize die wirkliche Größe des "Datenpakets" festhalten.
Mit der Prozedur Output will ich das "Datenpaket" dann wieder herausholen. Für das herausholen wollte ich dann durch _RealSize heraufinden wie groß das "Datenpaket" ist.

Soweit zur Theorie!
In der Praxis allerdings vergisst Delphi die Werte der Eigenschaften.
Das heißt wenn ich zum Beispiel bei Input _RealSize den Wert 11 zugewiesen habe, dann hatte _RealSize beim Aufruf von Output auf einmal den Wert 13514484 und _MaxSize den Wert 4372840 (zuvor hatte ich den Wert 500 abgespeichert).
Ganz so als würde Delphi den Speicherplatz für die Eigenschaften wieder freigeben weil es der Meinung ist das die Eigenschaften jetzt für nichts mehr gebraucht werden könnten.
Komisch ist auch, dass nicht immer alle Werte verloren gehen. Teilweise ist auch nur der Wert für _MaxSize verschwunden und _RealSize geblieben oder anders herum.

Ich wäre wirklich sehr dankbar wenn mir jemand erklären könnte was ich falsch gemacht habe oder mir eventuell einen Tip geben könnte wie ich dieses Problem umgehe. Folgend füge ich auch noch einmal den Quelltext an.

Schon einmal vielen Dank im voraus
Andre

Unit die die Klasse enthält :

Delphi-Quellcode:
unit U_Data;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

const
 dtNone   = -1;
 dtBool   = 0;
 dtByte   = 1;
 dtChar   = 2;
 dtString = 3;
 dtInteger = 4;
 dtReal   = 5;

type

 TArByte = array of Byte;

 TData = class
  private
   _Data : Pointer;
   _MaxSize, _RealSize, _DataType : Integer;
  public
   procedure Init(MaxSize, DataType : Integer);
   procedure Input(Data : Pointer; RealSize : Integer);
   procedure Output(var Data : Pointer);
 end;

implementation

procedure TData.Init(MaxSize, DataType : Integer);
begin
 _MaxSize := MaxSize;
 _DataType := DataType;
end;

procedure TData.Input(Data : Pointer; RealSize : Integer);
begin
 if RealSize <= _MaxSize then
  begin
   _RealSize := RealSize;
   GetMem(_Data, RealSize);
   Move(Data, _Data, RealSize);
  end
 else
  ShowMessage('Speicherplatz überschritten!');
end;

procedure TData.Output(var Data : Pointer);
begin
 GetMem(Data,_RealSize);
 Move(_Data,Data,_RealSize);
end;
Unit des Hauptprogrammes (Hier wollte ich die Prozeduren mal ausprobieren) :

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, U_Data;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  D : TData;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 D := TData.Create;
 D.Init(500,1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 arB : array[0..10]of Byte;
 I : Integer;
begin
 for I := 0 to 10 do
  arB[I] := I;
 D.Input(@arB,SizeOf(arB));
end;

procedure TForm1.Button3Click(Sender: TObject);
var
 arB : pointer;
 a : Tarbyte;
 I : Integer;
begin
 D.OutPut(arB);
 a := TArByte(arb);
 for I := 0 to 10 do
  Caption := Caption + IntToStr(a[I]);
end;

end.

Uwe Raabe 25. Aug 2011 18:24

AW: Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
Ändere mal diese Zeile

Delphi-Quellcode:
Move(Data, _Data, RealSize);
in diese

Delphi-Quellcode:
Move(Data^, _Data^, RealSize);

himitsu 25. Aug 2011 18:44

AW: Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
Und nicht die ganzen Speicherlecks vergessen.


Der von Output reservierte Speicher wird nicht freigegeben.
Auch würde ich dort eher OUT statt VAR deklarieren, da du ja die eingehenden Werte des Parameters ignorierst.

Und wurde schonmal über Input was zugewiesen, wird bei nächster Zuweisung das vorherrige ignoriert und nicht freigegeben.
Auch wird das am Ende nicht wieder freigegeben.

Andre93 25. Aug 2011 18:45

AW: Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
hey super!
das funktioniert!!
vielen vielen Dank für die schnelle hilfe.
ich hätte nie damit gerechnet dass ich so schnell eine antwort bekomme.
echt klasse.
kannst du mir vielleicht erklären warum das so geht und warum anders nicht. mit diesen ganzen pointer geschichten habe ich nämlich noch ab und zu so meine probleme. vor allem verstehe ich nicht ganz warum probleme bei den anderen eigenschaften auftreten, weil der move befehl macht ja überhaupt nichts mit diesen eigenschaften. für den sind ja eigentlich nur data, _data und die größe meines datenpaket wichtig.
würde mich echt mal interessieren, aber bis hier erst einmal danke das hat mir schon sehr geholfen

himitsu 25. Aug 2011 18:49

AW: Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
Du willst doch den Inhalt kopieren und da Move als VAR/CONST Parameter deklariert ist, mußt du deine Zeiger erst dereferenzieren, damit der Inhalt übergibt wird.

Ohne Dereferenzierung kopierst du die Zeiger und nicht das worauf die Zeiger zeigen.

Bei RealSize > SizeOf(Pointer) handelst du dir dann auch noch einen Bufferoverrun ein.

Andre93 25. Aug 2011 21:38

AW: Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
@himitsu
ich hab da noch mal ein paar fragen
du hast geschrieben:
Zitat:

Und wurde schonmal über Input was zugewiesen, wird bei nächster Zuweisung das vorherrige ignoriert und nicht freigegeben.
also muss ich bevor ich ein weiteres mal input mache, um die gespeicherten werte zu verändern, vorher den speicherbereich der meine alten werte beinhaltet wieder freigeben? das mach ich einfach mit
Delphi-Quellcode:
FreeMem(_Data);
oder?

Und du meintest :
Zitat:

Der von Output reservierte Speicher wird nicht freigegeben.
In Output reserviere ich doch den Speicherbereich auf den der pointer zeigt den ich beim aufruf von output übergebe. wenn ich diesen speicher gleich wieder freigebe, dann gebe ich doch das wieder frei was so zu sagen mein "rückgabewert" ist. und mit diesem "rückgabewert" will ich ja nach dem aufruf von output weiterarbeiten, da wäre es ja schlecht wenn der schon wieder freigegeben ist, oder? Tut mir leid, ich schätze ich habs falsch verstanden, weil mir hier evtl. ein paar grundlagen in sachen gesetzmäßigkeiten von übergaben usw. fehlen.

DeddyH 26. Aug 2011 07:09

AW: Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
Als Faustregel gilt: 1 GetMem -> 1 FreeMem, 1 New -> 1 Dispose
Wo man das macht hängt davon ab, wie lange man die Daten braucht, aber irgendwo muss es sein (zur Not im Destruktor).

sx2008 27. Aug 2011 01:05

AW: Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
Mir scheint du bist mit einem TMemoryStream oder TStringStream besser bedient als mit deiner eigenen Klasse.
Du könntest auch ein TMemoryStream-Objekt innerhalb deiner eigenen TData-Klasse benützen.

Andre93 29. Aug 2011 19:44

AW: Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
hey,
bis hierher schon mal vielen dank an alle...
im moment hab ich noch ein anderes problem. das ist wahrscheinlich ein ganz einfacher fehler aber ich sitze jetzt schon ne ganze weile dran und bekomme es nicht hin.

ich wollte nun nicht immer das gleiche abspeichern, sondern nun irgendeinen Text aus einem editfeld.
bloß in dem moment wo ich das array dynamisch erzeuge funktioniert es nicht mehr.

also das hier funktioniert noch :
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
 arB : array[0..10] of Byte;
 I, Len : Integer;
begin
 len := length(Edit1.Text);
 for I := 0 to len - 1 do
  arB[I] := ord(Edit1.Text[I+1]);
 D.Input(@arB,len);
end;
da ist ja schon vorher die größe arrays festgesetzt.

Das hier geht allerdings nicht mehr:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
 arB : array of Byte;
 I,Len : Integer;
begin
 len := length(Edit1.Text);
 GetMem(arB,len);
 for I := 0 to len - 1 do
  arB[I] := ord(Edit1.Text[I+1]);
 D.Input(@arB,len);
 FreeMem(arB,len);
end;
da liefert "output" nicht mehr die richtigen werte, sondern irgendwelche anderen.

himitsu 30. Aug 2011 02:23

AW: Delphi vergisst die Werte der Eigenschaften meiner Klasse
 
GetMem? :gruebel:
Delphi-Referenz durchsuchenSetLength

Welche Delphiversion nutzt du nochmal? (PS: sowas kann man auch gleich mit im Foren-Profil mit nennen)
Seit Delphi 2009 ist ein SizeOf(Char) = 2 und nicht SizeOf(Byte).


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:52 Uhr.
Seite 1 von 2  1 2      

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