![]() |
Probleme mit FreeandNil
Moin,
ich nehme an so einem Turnier, organisiert von der Uni Kiel teil: ![]() Da ich leider selbst nicht allzuviel Ahnung vom Programmieren habe wende ich mich an euch und zwar: Ich lege mir in der USimpleAI ein Record an mit allen möglichen Zügen: TMovesWithPoints = record move : TMove; points : TSingleScoreData; pointscount : Integer; stoneindex : Integer; ChuckNorris: Integer; Und am Ende wird der "beste" Zug aus diesem Array ausgewählt (sprich der, bei dem der Chuck Norris Wert am höchsten ist ^^). Danach will ich das Record per Freeandnil wieder freigeben, jedoch bekomme ich dann jedesmal eine Fehlermeldung vom Server "Received Null String" Nu hab ich mich schlau gemacht und mir wurde gesagt, dass das Result nicht absolut gespeichert wird, sondern als Zeiger auf den Eintrag im Record, deshalb hab ich mir den Move als solchen mit allen Daten des besten Moves neu generiert: function Finalmove(Move: TMove): TMove; var stone: TStone; f1, f2: Integer; c1,c2: TCoordinate; begin f1:=move.stone.getSymbol(0); f2:=move.stone.getSymbol(1); Stone:= TStone.Stone(f1,f2); c1:= move.getCoordinates[0]; c2:= move.getCoordinates[1]; result:= TMove.TMove(Stone,c1,c2); end; Und das Ergebnis dieser Funktion wird als Result der Hauptfunktion ausgespuckt und hinterher das Record freigegeben. Gibt aber trotzdem wieder diese Fehlermeldung. Ich hab mich per F7 mal durch den Code geklickert... Man kommt dabei in die CPU Ansicht des Freeandnil befehls und bevor (!) er ganz durch ist, kommt die Fehlermeldung vom Server "Received Null String". Dabei ist es egal, ob ich den Befehl vor oder nachs result:= setze. Deshalb wundert mich das ganze auch so, der Ausgabewert dieser Funktion wird nämlich erst in der UNetwork letztlich weggeschickt, aber bis dahin kommt er erst garnicht, wenn ich das FreeAndNil drinlasse. Wenn ihr noch irgendwelche Infos braucht, kein Problem. Danke schonmal für Antworten, ohne die Freigabe kann ichs ziemlich vergessen, da ich nach 10 Zügen ne Speicherausnutzung von 500MB hab... Gruß Maurice |
Re: Probleme mit FreeandNil
Bitte formatiere Delphi-Code mit den [ delphi ] ... [ /delphi ] Tags.
Einen Record brauchst du nicht freigeben, wenn du ihn nicht reserviert hast. Was ist TMove? Eine Klasse? Wenn ja, mußt du in deinem Record diese auch mit MovesWithPoints.Move := TMove.Create erzeugen. |
Re: Probleme mit FreeandNil
Moin,
Zitat:
Zitat:
Delphi-Quellcode:
Dazu:
constructor TMove.TMove( pid,ChuckNorris: Integer; st: TStone; const c1, c2: TCoordinate );
begin FplayerID := pid; Fstone := st; SetLength( Fcoordinates, 2 ); Fcoordinates[0] := TCoordinate.TCoordinate( c1.x, c1.y ); Fcoordinates[1] := TCoordinate.TCoordinate( c2.x, c2.y ); end;
Delphi-Quellcode:
Habe jetzt etwas herausgefunden: Wenn ich nicht das Moves Record freigeben will, sondern ein anderes, was ich in der SimpleAI benutze, dann passiert folgendes:
constructor TMove.TMove( st: TStone; x1, y1, x2, y2: Integer );
begin FplayerID := -1; Fstone := st; SetLength( Fcoordinates, 2 ); Fcoordinates[0] := TCoordinate.TCoordinate( x1, y1 ); Fcoordinates[1] := TCoordinate.TCoordinate( x2, y2 ); end; Er geht bei dieser Funktion, aus der heraus er die SimpleAI aufruft:
Delphi-Quellcode:
normalerweise auf diese Zeile: m := handler.myTurn( serverMessage );
function TNetwork.processMessage( handler: TMessageHandler ): Boolean;
var msgs: TStringList; serverMessage, mStr: String; identifier: Char; m: TMove; tmp: TBoardData; tmpS: TScoreData; i, j, number, playerNum, k: Integer; msg: TStringTokenizer; handled: Boolean; stones: TStoneArray; begin // warte auf Servernachricht msgs := Fsocket.receiveLn(); result := True; for k := 0 to msgs.Count - 1 do begin serverMessage := msgs[k]; WriteLn( '> ' + serverMessage ); msg := TStringTokenizer.TStringTokenizer( serverMessage ); try handled := False; if ( Length( serverMessage ) > 0 ) then begin mStr := msg.nextToken(); // lies den Nachrichtenidentifier aus identifier := mStr[1]; // untersuche identifier und verarbeite entsprechende Nachricht case identifier of MESSAGE_SERVER_INITIAL: begin number := StrToInt( msg.nextToken() ); Fboard^.playerID := number; handler.initialMessage( serverMessage ); handled := True; end; MESSAGE_SERVER_STONES: begin unserializeStone( serverMessage, stones ); handler.newStones( stones ); handled := True; end; MESSAGE_SERVER_REQUEST_MOVE: begin Fboard^.update( serverMessage ); m := handler.myTurn( serverMessage ); m.playerID := Fboard^.playerID; Fboard^.update( m ); sendMove( m ); handled := True; end; MESSAGE_SERVER_ANSWER_BOARD: begin for i := 0 to 10 do begin for j := 0 to 10 do begin number := StrToInt( msg.nextToken() ); tmp[i][j] := number; end; end; Fboard^.update( tmp ); handled := True; end; MESSAGE_SERVER_ANSWER_SCORE: begin for playerNum := 0 to 1 do begin for j := 0 to 5 do begin number := StrToInt( msg.nextToken() ); tmpS[playerNum][j] := number; end; end; Fboard^.updateScores( tmpS ); handled := True; end; MESSAGE_SERVER_RESET: begin handler.reset( serverMessage ); handled := True; end; MESSAGE_SERVER_REQUEST_CHANGE: begin if ( handler.changeRequest( serverMessage ) ) then mStr := MESSAGE_CLIENT_ANSWER_CHANGE + ' ' + MESSAGE_CLIENT_ANSWER_CHANGEACCEPT else mStr := MESSAGE_CLIENT_ANSWER_CHANGE + ' ' + MESSAGE_CLIENT_ANSWER_CHANGEREJECT; sendString( mStr ); handled := True; end; MESSAGE_SERVER_TERMINATE: begin disconnect(); handler.terminate( serverMessage ); handled := True; end; end; end; result := handled and result; finally FreeAndNil( msg ); end; end; FreeAndNil( msgs ); end; Wenn ich allerdings den Freeandnilbefehl drinhab, dann geht er nach der SimpleAI direkt auf diese: result := handled and result; Er überspringt also das senden und deshalb gibts die Fehlermeldung, es wird also irgendwo in dem Grundgerüst des Clients n Fehler sein. Wenn irgendwer da die Lust zu hat, sich das mal anzugucken, dem kann ich meinen aktuellen Client gerne mal schicken, ansonsten werde ich denke ich das Record so umschreiben müssen, dass es nurnoch Integerwerte enthält, die er dann automatisch wieder freigibt. Gruß Maurice |
Re: Probleme mit FreeandNil
Sicher, dass "constructor TMove.TMove" funktioniert? Kenne nur die "constructor TMove.Create"-Variante.
Den Code hab ich mir da nicht angeguckt. Aber du versuchst wohl irgendwas freizugeben, was du nicht / falsch reserviert hast. |
Re: Probleme mit FreeandNil
Der Konstructor funktioniert schon, ausser dass mann dann TMove.TMove schreiben muss anstelle von TMove.Create.
@FreeAndNil: Probier doch mal anstelle FreeAndNil(Obj); lieber Obj.Free; Obj:=Nil; zu schreiben. FreeAndNil heisst nämlich falsch. Es müsste NilAndFree heissen, weil innerhalb dieser funktion wird das übergebene Objekt erst gemerkt, dann der übergebene Zeiger genilt und danach erst das Objekt freigegeben. Hat bei mir in der Firma schon zu langen debugorgien geführt. |
Re: Probleme mit FreeandNil
Zitat:
|
Re: Probleme mit FreeandNil
Zitat:
2.) FreeAndNil setzt Nachkommen von TObject voraus ... Ist diese Voraussetzung bei dir gegeben ?(Vermisse Inherited in deinem Constructor) 3.) Schliesse mich auch Muetze1 an... |
Re: Probleme mit FreeandNil
Zitat:
Zitat:
|
Re: Probleme mit FreeandNil
@mkinzler:
Das bedeuted, daß
Delphi-Quellcode:
dasselbe ist wie
....=Class
Delphi-Quellcode:
?
...=Class(tObject)
|
Re: Probleme mit FreeandNil
Ja
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz