| Autor |
Beitrag |
WOOH
Hält's aus hier
Beiträge: 8
|
Verfasst: Fr 30.01.09 15:43
Ich arbeite grade an meiner Facharbeit und hab den Code schon fast fertig.
Das Problem ist, dass ich ab und zu ein paar Fehler des Types EAccesviolation bekomme, ich aber keine Idee hab, was mit dieser Fehlermeldung gemein sein könnte. Am besten ich poste mal den Code an der Stelle wo mir das Programm abschmiert.
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: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| function Tform1.zweivs1(reizwert:integer):integer; var neu:integer; begin ShowMessage('Spieler '+inttostr(spielerfestlegen(geber,2))+' Bitte reizen Sie.'#13#10'Geben Sie 0 ein um zu passen'); zeigen(spielerfestlegen(geber,2),false); neu:= strtoint(inputBox('Spieler '+inttostr(spielerfestlegen(geber,2)),'Bitte den Reizwert eingeben',inttostr(Reizwert+1))); Form2.Destroy; if neu = 0 then result:= nullvs1(Reizwert) else begin if neu <= reizwert then begin showmessage('Bitte einen Wert größer als der alte Reizwert eingeben'); result := zweivs1(reizwert); end else begin zeigen(Spielerfestlegen(geber,1),false); if messagedlg('Spieler '+ inttostr(spielerfestlegen(geber,1))+' Wollen Sie bei einen Reizwert von '+inttostr(neu)+' mitgehen?',mtConfirmation,mbYesNOcancel,0) = mryes then result := zweivs1(neu) else result := nullvs2(neu); Form2.Destroy; end; end; end;
function Tform1.nullvs1(reizwert:integer):integer; var neu:integer; begin ShowMessage('Spieler '+inttostr(geber)+' Bitte reizen Sie.'#13#10'Geben Sie 0 ein um zu passen'); zeigen(geber,false); neu:= strtoint(inputBox('Spieler '+inttostr(geber),'Bitte den Reizwert eingeben',inttostr(Reizwert+1))); Form2.Destroy; if neu = 0 then result:= spielerfestlegen(geber,1) else begin if neu <= reizwert then begin showmessage('Bitte einen Wert größer als der alte Reizwert eingeben'); result := nullvs1(reizwert); end else begin zeigen(Spielerfestlegen(geber,1),false); if messagedlg('Spieler '+ inttostr(spielerfestlegen(geber,1))+' Wollen Sie bei einen Reizwert von '+inttostr(neu)+' mitgehen?',mtConfirmation,mbYesNOcancel,0) = mryes then result := nullvs1(neu) else result := geber; Form2.Destroy; end; end; end;
function Tform1.nullvs2(reizwert:integer):integer; var neu:integer; begin ShowMessage('Spieler '+inttostr(geber)+' Bitte reizen Sie.'#13#10'Geben Sie 0 ein um zu passen'); zeigen(geber,false); neu:= strtoint(inputBox('Spieler '+inttostr(geber),'Bitte den Reizwert eingeben',inttostr(Reizwert+1))); Form2.Destroy; if neu = 0 then result:= spielerfestlegen(geber,2) else begin if neu <= reizwert then begin showmessage('Bitte einen Wert größer als der alte Reizwert eingeben'); result := nullvs2(reizwert); end else begin zeigen(Spielerfestlegen(geber,2),false); if messagedlg('Spieler '+ inttostr(spielerfestlegen(geber,2))+' Wollen Sie bei einen Reizwert von '+inttostr(neu)+' mitgehen?',mtConfirmation,mbYesNOcancel,0) = mryes then result := nullvs2(neu) else result := geber; Form2.Destroy; end; end; end; |
Die Variable Geber ist global in der selben Unit deklariert.
Ich hoffe auf schnelle Antworten.
Wenn es hilft kann ich den Code auch ganz hochladen, da aber bitte einmal als Antwort posten, sonst mach ich mir die Arbeit nicht :) Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Fr 30.01.2009 um 15:58
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Fr 30.01.09 15:49
Du gibst ja andauernd den Speicher der Form2 frei, obwohl diese wahrscheinlich garnicht mehr existiert, weil du ihren Speicher schon vorher freigegeben hast! Das kann ja nur schiefgehen 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
WOOH 
Hält's aus hier
Beiträge: 8
|
Verfasst: Fr 30.01.09 15:52
Achja was noch zu erwähnen wäre:
In der Procedure Zeigen wird Form2 jedesmal wieder createt.
Am besten poste ich das auch mal:
Delphi-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:
| procedure TForm1.zeigen (Spieler:integer;modal:boolean); var i:integer; begin Form2 := Tform2.Create(Form1); if Spieler = 1 then begin Form2.Caption := 'Spieler 1'; for i:= 1 to 10 do Form2.Listbox1.Items.Add(stringf(Spieler1Karten[1,i])+' , '+stringw(Spieler1Karten[2,i])); if modal = true then Form2.ShowModal else form2.Show; end; if Spieler = 2 then begin Form2.Caption := 'Spieler 2'; For i:= 1 to 10 do Form2.Listbox1.Items.Add(stringf(Spieler2Karten[1,i])+' , '+stringw(Spieler2Karten[2,i])); if modal = true then Form2.ShowModal else form2.Show; end; if Spieler = 3 then begin Form2.Caption := 'Spieler 3' ; For i:= 1 to 10 do Form2.Listbox1.Items.Add(stringf(Spieler3Karten[1,i])+' , '+stringw(Spieler3Karten[2,i])); if modal = true then Form2.ShowModal else form2.Show; end; if modal = true then Form2.Destroy; end; |
Und Spielerfestlegen gibt auch nur Zahlen von 1 bis 3 zurück, nur damit keiner auf die Idee kommt, dass es daran liegen könnte.
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Fr 30.01.09 15:57
WOOH hat folgendes geschrieben : | Achja was noch zu erwähnen wäre:
In der Procedure Zeigen wird Form2 jedesmal wieder createt. |
 Grausiger Programmierstil! Wieso tust du sowas! Das frisst Leistung und macht dein Programm unnötig langsam!
Nutze zum Verstecken einer Form ihre .Hide Methode und zum Anzeigen die .Show oder .ShowModal (in diesem Fall wird die aufrufende Form "gesperrt", wie wenn du z.B. eine Showmessage anzeigst).
Die Form2 wird im normalfall bereits in der .dpr-Datei erzeugt über Application.CreateForm, darum musst du dich also nicht selber kümmern.
Edit: Zum Freigeben des Speichers sollte man übrigens nicht .Destroy direkt aufrufen, sondern stattdessen .Free 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 30.01.09 15:59
Du solltest dir dringend angewöhnen ein Objekt auch da wieder freizugeben wo du es erstellst, wenn das (wie in diesem Fall) möglich ist.
Zudem solltest du niemals den Destruktor (Destroy) direkt aufrufen, sondern stattdessen Free benutzen. Das prüft, ob das Objekt überhaupt noch existiert, bevor versucht wird den Speicher freizugeben. Und wenn du das Objekt später wieder verwendest, dann ist FreeAndNil am besten, weil danach die Variable nil ist.
Bei einem Formular kannst du auch in OnClose Action auf caFree setzen, dann wird dieses automatisch aus dem Speicher entfernt, wenn du das Formular schließt.
Zudem reicht es auch, wenn du das zweite Formular einmal erzeugst oder es automatisch erzeugen lässt, dann hast du den ganzen Ärger mit erzeugen und freigeben nicht. Aber wenn du es schon immer wieder erzeugst, dann solltest du zumindest (wie gesagt) es dort auch wieder freigeben wo du es erzeugst. (Also in der selben Prozedur / Funktion)
|
|
WOOH 
Hält's aus hier
Beiträge: 8
|
Verfasst: Fr 30.01.09 16:00
Ich hab das so gemacht, weil wir das in der Schule genau so vor n paar Wochen durchgenommen haben, und da wir in der Facharbeit ja Sachen aus der Schule einbinden müssen, und ich keine bessere Methode feststellen konnte, hab ich das einfach mal so gemacht.
Es kann sein, dass das langsam ist, aber das ist die schnellste Methode die mir eingefallen ist.
Achja btw. Form2 wird nicht autocreatet, weil ich das umgestellt habe.
Edit:
Ich hatte das ursprünglich in Zeigen auch wieder zerstört, das lief allerdings nur so lange gut bis ich die Möglichkeit des Modalen eingebaut habe, und da ich nicht will, dass es sofort zerstört wird nachdem ich es createt habe, musste ich den Destruktor in der Funktion aufrufen.
edit2: ich probiers mit dem Free heute abend mal aus, da ich jetzt zum Orgelunterricht muss.
Danke für den tip.
edit3:
Die Fehlermeldung tritt nur bei den Functions nullvs1 und nullvs2 auf, und auch nur wenn ich bei dem Msdialog nicht auf Ja klicke.
Vlt liegts daran
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 30.01.09 16:07
Dir ist aber schon klar, dass der Quelltext nach zeigen sofort ausgeführt wird, wenn du darin Form2 nicht modal anzeigst, oder? Und damit wird Destroy auch sofort aufgerufen...
Dann machst du sowas: Delphi-Quelltext Das ist falsch. Warum kannst du hier nachlesen:
www.delphi-treff.de/...olean-werten/page/4/
Richtig: Delphi-Quelltext
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Fr 30.01.09 16:12
Ich sehe gerade: Klickst du auf "ja" im messagedlg, dann wird dein zweivs0 rekursiv aufgerufen, bevor die form2 freigegeben wird, wodurch die form ein zweites mal erzeugt wird, dabei geht die alte Instanz aber in den unendlichen Weiten des Speichers verloren  . Die Form wird am Ende der funktion wieder freigegeben, dann springst du einen rekursionsschritt zurück und gibst sie nochmal frei, und bumm, Zugriffsverletzung 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
WOOH 
Hält's aus hier
Beiträge: 8
|
Verfasst: Fr 30.01.09 18:56
Herzlichen Dank, das war wahrscheinlich der Fehler.
Und ich dachte ich hätte ein ernstahftes Zeitproblem wegen der Fehlermeldung.
Aber dank Euch werd ich es noch schaffen.
Wenn ihr wollt kann ich euch die Note am ende mitteilen.
P.S. Ich werde das löblich erwähnen, dass ihr mir geholfen habt.
edit: jetz klappst^^ danke nochmal
|
|
WOOH 
Hält's aus hier
Beiträge: 8
|
Verfasst: So 01.02.09 15:24
jaenicke hat folgendes geschrieben : | Dir ist aber schon klar, dass der Quelltext nach zeigen sofort ausgeführt wird, wenn du darin Form2 nicht modal anzeigst, oder? Und damit wird Destroy auch sofort aufgerufen...
|
deshalb hab ich den destruktor in dem fall nicht in die prozedur zeigen gesetzt.
weil entweder wirds modal angezeigt, dann wirds nachdem es geschlossen wird zerstört,
oder es wird nicht modal angezeigt, dann wirds durch den destuktor in der function zweivs1 etc. zerstört.
deshalb war es nicht möglich ohne den quelltext groß umzubauen den destruktor komplett in zeigen zu stellen
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: So 01.02.09 15:50
Man soll ja auch zum Einzeigen/Verstecken einer Form nicht Create/Free nutzen sondern Show/ShowModal/Hide  Du solltest das wirklich umstellen, das ist einfach keine Lösung für das Problem.
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 01.02.09 16:26
Ich meinte das: WOOH hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3:
| zeigen(spielerfestlegen(geber,2),false); neu:= strtoint(inputBox('Spieler '+inttostr(spielerfestlegen(geber,2)),'Bitte den Reizwert eingeben',inttostr(Reizwert+1))); Form2.Destroy; | |
Das Fenster wird nicht modal angezeigt, d.h. sobald du die InputBox weg klickst wird Form2 zerstört...
Denn der Quelltext wird eben sofort ausgeführt und nicht nachdem Form2 geschlossen wurde...
JayEff hat schon Recht. Man muss zwar nicht gleich alles beim Start erzeugen, das dauert bei größeren Projekten zu lange. Aber ich prüfe einfach ob es schon erstellt wurde und wenn nicht erstelle ich es vor der ersten Verwendung. Danach ist das Fenster dann immer schon vorhanden.
|
|
WOOH 
Hält's aus hier
Beiträge: 8
|
Verfasst: So 01.02.09 20:35
Okay, da habt ihr schon recht, aber das lag daran, dass ich die procedure zeigen ursprünglich nur 1mal aufrufen wollte.
Und dann hat sich im Laufe der Zeit es so ergeben, dass das öfters benutzt wurde, und dann noch die modal option dazugekommen ist, deshalb mag der stil jetz was abstrus sein, aber es wurde nach gutdünken programmiert ohne da vorher richtig nachgedacht zu habn, deshalb is das n bissel komisch.
Wenn ich da ne Woche einfach an nem großen Struktogram gearbeitet hätte wäre das ganze was übersichtlicher ausgefallen.
Da dies aber nicht ist, muss ich jetz mit dem Code so leben wie er ist, da ich nicht mehr die Zeit habe, das groß zu verändern.
Danke für die Rückmeldungen
|
|
|