Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Warum AccessViolation? (https://www.delphipraxis.net/7307-warum-accessviolation.html)

moin339 8. Aug 2003 18:26


Warum AccessViolation?
 
Moin!

Ich habe hier ein kleines testprogramm. Wenn ich zuerst auf Button1 und dannach auf Button2 klicke bekomme ich eine AccessViolation, obwohl die Variable eigentlich definiert ist. Wisst ihr wodran das liegt?

Delphi-Quellcode:
  TTest = class
  private
    TestString : string;
  public
    constructor create;
    procedure ShowString;
  end;

var
  Form1 : TForm1;
  test : TTest;

implementation

{$R *.dfm}

constructor TTest.create;
begin
  TestString := 'Hallo';

  while true do
  begin
    Application.ProcessMessages;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  test := TTest.create;
  test.free;
end;

procedure TTest.ShowString;
begin
  ShowMessage(TestString); // Exception: EAccessViolation
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  test.ShowString;
end;
ciao, moin399 :coder:

Keldorn 8. Aug 2003 18:28

Re: Warum AccessViolation?
 
:wiejetzt:
Zitat:

test := TTest.create;
test.free;
was glaubst du, was ein free macht?


Mfg Frank

Keldorn 8. Aug 2003 18:32

Re: Warum AccessViolation?
 
Zitat:

while true do
begin
Application.ProcessMessages;
end;
was hat das denn so eine endlosschleife im constructor zu suchen ?

moin339 8. Aug 2003 18:46

Re: Warum AccessViolation?
 
Würde das ganze funktionieren wenn die endlosschleife in einer anderen methode von TTest ist, also nicht im constructor? (habe hier grad kein Delphi)

moin339

Luckie 8. Aug 2003 19:20

Re: Warum AccessViolation?
 
Du kannst die Endlosschleife hinpacken wohin du willst. Aber was meinst du wie viel Instanzen deines Objektes noch existieren, wenn du nach Create gleich ein Free wieder aufrufst?

Marco Haffner 8. Aug 2003 19:21

Re: Warum AccessViolation?
 
Also den Fehler hat jetzt sogar mein Cousin gefunden und der hat noch nie Programmiert.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  test := TTest.create;
  test.free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  test.ShowString;
end;
Das kann so nicht funktionieren. In Button1Click erzeugst Du die Variable Test, gibst sie aber auch gleich wieder frei.
Das heißt, wenn Du Button2 anklickst ist Test schon längst wieder freigegeben.

moin339 8. Aug 2003 20:27

Re: Warum AccessViolation?
 
Schön, Schön. Bloß wenn ich die "test.free" Zeile lösche passiert das gleiche. Free wird ja auch nicht ausgeführt, da create nicht fertig werden kann (ist ja auch eine ENDLOS-Schleife)

Probiert den code doch bitte mal selber aus

ciao, moin339

Luckie 8. Aug 2003 20:29

Re: Warum AccessViolation?
 
Stimmt auch wieder. Aber in diesem Fall wird die Instanz deines Objektes nie erstellt.

Was soll der Blödsinn mit der Endlosschleife überhaupt im Konstruktor?

moin339 8. Aug 2003 20:43

Re: Warum AccessViolation?
 
Zitat:

Zitat von Luckie
Was soll der Blödsinn mit der Endlosschleife überhaupt im Konstruktor?

Ich schreibe eine GUI für ein consolen programm und starte im constructor einer klasse das programm und prüfe auf neue daten (das ganze in einer schleife, die erst verlassen wird wenn das consolen-programm beendet ist)

Zitat:

Zitat von Luckie
Stimmt auch wieder. Aber in diesem Fall wird die Instanz deines Objektes nie erstellt.

Würde das ganze funktionieren wenn die endlosschleife in einer anderen methode von TTest ist, also nicht im constructor?

ciao, moin339

Keldorn 8. Aug 2003 20:55

Re: Warum AccessViolation?
 
irgendwie sehe ich keinen Sinn darin
Zitat:

(das ganze in einer schleife, die erst verlassen wird wenn das consolen-programm beendet ist)
wann wird denn deine endlosschleife verlassen? doch nie, oder? es gibt doch gar keine Abbruchgbedingung ...

außerdem, wenn du das application.processmessages so inder schleife drinläßt, wird dein CPU-Belastung auf 100% gehen. wenn schobn, dann setzt ein sleep mit rein

moin339 8. Aug 2003 21:00

Re: Warum AccessViolation?
 
die endlosschleife war hier nur ein beispiel. übrigens habe ich keine prozessor-Belastung von 100%.

Chewie 9. Aug 2003 10:32

Re: Warum AccessViolation?
 
Zitat:

Zitat von Keldorn
außerdem, wenn du das application.processmessages so inder schleife drinläßt, wird dein CPU-Belastung auf 100% gehen. wenn schobn, dann setzt ein sleep mit rein

Bei einem Konsolenprogramm, das gar keine Nachrichtenschleife hat, müssen auch keine Nachrichten abgearbeitet werden. Deswegen macht das auch nichts aus.

Wenn du die Konsole mittels einer Endlosschlkeife am Laufen lassen willst, kannst du auch einen extra Thread benutzen.

moin339 9. Aug 2003 10:41

Re: Warum AccessViolation?
 
argh. ihr versteht mich nicht oder könnt nicht lesen ;-) . Ich möchte eine GUI für ein FREMDES Consolen-Programm schreiben. In meinem Delphiprogramm prüfe ich in einer schleife, die erst verlassen wird wenn das FREMDE Consolen-Programm beendet ist, ob in der Console neue Ausgaben stehen.

ciao, moin339

Pascal 11. Aug 2003 22:45

Re: Warum AccessViolation?
 
Du möchtest Create so lange aufrufen, bis dein fremdes Programm fertig ist, wenn ich das richtig verstanden habe.
Erstens: Wenn du bei klick Button1 dein Objekt kreierst und danach direkt wieder frei gibst, exisitiert dies natürlich auch nicht mehr, also weg damit.

Zweitens: Wenn du in deinen Construktor eine Endlosschleife einbaust, wird dein Objekt nie vollständig kreiert und somit kannst du auch nicht auf das Objekt zugreifen.
Dein Konsolenprogramm wird aber irgend wann mal fertig sein, dann wird das Objekt kreiert und dann kannst du auch auf dein Objekt zugreifen.

Am besten schmeiß diese Abfrage aus Create und schreibe eine neue Funktion. Dann ist dein Objekt auf jeden Fall mal da --> keine Zugriffsverletzung mehr!
Dann baue einfach mal eine Schleife, die auch fertig wird, dann kommst du deiner späteren Anwendung schon näher.

Gruß Pascal

neolithos 12. Aug 2003 07:20

Re: Warum AccessViolation?
 
Delphi-Quellcode:
  TTest = class
  private
    TestString : string;
  public
    constructor create;
    procedure DoSomething;
    procedure ShowString;
  end;

var
  Form1 : TForm1;
  test : TTest;

implementation

{$R *.dfm}

constructor TTest.create;
begin
  inherited;
  TestString := 'Hallo';
end;

procedure TTest.DoSomething;
begin
  while true do
  begin
    Application.ProcessMessages;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  test := TTest.create;
  test.DoSomething;
  test.free;
end;

procedure TTest.ShowString;
begin
  ShowMessage(TestString); // Exception: EAccessViolation
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  test.ShowString;
end;
In deine alten wurde die Instance noch nihct freigegeben so schon.

Schon mal was von TThread's gehört?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:52 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