Detach the state when copying a position
authorMarco Costalba <mcostalba@gmail.com>
Fri, 29 May 2009 15:23:21 +0000 (17:23 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 29 May 2009 15:23:21 +0000 (17:23 +0200)
In Position we store a pointer to a StateInfo record
kept outside of the Position object.

When copying a position we copy also that pointer so
after the copy we have two Position objects pointing
to the same StateInfo record. This can be dangerous
so fix by copying also the StateInfo record inside
the new Position object and let the new st pointer
point to it. This completely detach the copied
Position from the original one.

Also rename setStartState() as saveState() and clean up
the API to state more clearly what the function does.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/position.cpp
src/position.h
src/uci.cpp

index dd6ec05b929d70088c68fd8a3aa40b77486680fb..480a92ec9cfcd1a7e3850aea8fbc94f61c570ece 100644 (file)
@@ -315,9 +315,10 @@ void Position::print(Move m) const {
 
 /// Position::copy() creates a copy of the input position.
 
-void Position::copy(const Position &pos) {
+void Position::copy(const Positionpos) {
 
   memcpy(this, &pos, sizeof(Position));
+  saveState(); // detach and copy state info
 }
 
 
@@ -1607,15 +1608,16 @@ int Position::see(Square from, Square to) const {
 }
 
 
-/// Position::setStartState() copies the content of the argument
+/// Position::saveState() copies the content of the current state
 /// inside startState and makes st point to it. This is needed
 /// when the st pointee could become stale, as example because
 /// the caller is about to going out of scope.
 
-void Position::setStartState(const StateInfo& s) {
+void Position::saveState() {
 
-  startState = s;
+  startState = *st;
   st = &startState;
+  st->previous = NULL; // as a safe guard
 }
 
 
@@ -1966,7 +1968,7 @@ void Position::init_piece_square_tables() {
 /// the white and black sides reversed. This is only useful for debugging,
 /// especially for finding evaluation symmetry bugs.
 
-void Position::flipped_copy(const Position &pos) {
+void Position::flipped_copy(const Positionpos) {
 
   assert(pos.is_ok());
 
index aa7c7ab8b78754e19728afd59512c7deff736ec5..9737d7614981756382ab2fc150f149fa24f95c2b 100644 (file)
@@ -138,8 +138,8 @@ public:
   void print(Move m = MOVE_NONE) const;
 
   // Copying
-  void copy(const Position &pos);
-  void flipped_copy(const Position &pos);
+  void copy(const Positionpos);
+  void flipped_copy(const Positionpos);
 
   // The piece on a given square
   Piece piece_on(Square s) const;
@@ -250,7 +250,7 @@ public:
   bool square_is_weak(Square s, Color c) const;
 
   // Doing and undoing moves
-  void setStartState(const StateInfo& st);
+  void saveState();
   void do_move(Move m, StateInfo& st);
   void do_move(Move m, StateInfo& st, Bitboard dcCandidates);
   void undo_move(Move m);
index a64520050f084e481cc2804aba1dec5406f21c66..4a333f70b7540b2d660070bf6579cfaafaa5cc50 100644 (file)
@@ -210,9 +210,9 @@ namespace {
                 if (RootPosition.rule_50_counter() == 0)
                     RootPosition.reset_game_ply();
             }
-            // Our StateInfo st is about going out of scope,
-            // so save its content before they disappear.
-            RootPosition.setStartState(st);
+            // Our StateInfo st is about going out of scope so copy
+            // its content inside RootPosition before they disappear.
+            RootPosition.saveState();
         }
     }
   }