Thema: Delphi Probleme mit FreeandNil

Einzelnen Beitrag anzeigen

Maurice

Registriert seit: 6. Feb 2008
2 Beiträge
 
#3

Re: Probleme mit FreeandNil

  Alt 6. Feb 2008, 16:35
Moin,

Zitat von Nuclear-Ping:
Bitte formatiere Delphi-Code mit den [ delphi ] ... [ /delphi ] Tags.
Wird gemacht.

Zitat:
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.
Ist passiert, ja. Der Constructor von TMove sieht so aus:
Delphi-Quellcode:
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;
Dazu:
Delphi-Quellcode:
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;
Habe jetzt etwas herausgefunden: Wenn ich nicht das Moves Record freigeben will, sondern ein anderes, was ich in der SimpleAI benutze, dann passiert folgendes:
Er geht bei dieser Funktion, aus der heraus er die SimpleAI aufruft:
Delphi-Quellcode:
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;
normalerweise auf diese Zeile: m := handler.myTurn( serverMessage );
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
  Mit Zitat antworten Zitat