Fix rare memory corruption in combat simulation
It occurred when a fight was simulated for a * slowed unit * that can level up after the fight * using Monte Carlo simulation. Monte_carlo_combat_matrix clears the matrix in constructor because it uses the matrix in a different way than probability_combat_matrix. Clearing was unnecessarily thorough and marked all the rows and columns as unused. If the unit was slowed before the fight, no values were ever placed to plane 0 (neither unit slowed). Thus, all the rows/columns in plane 0 were still marked as unused even after the simulation. After the Monte Carlo simulation, the simulation code considered the possibility that the unit may have leveled up. It does that by moving all the values that mean "combatant B dead" into the last row of plane 0, that means "combatant A full HP and not slowed". The code that moves the values assumes that at least one row and column is used. If none are, then it dereferences an invalid iterator and corrupts memory. I fixed the bug my making prob_matrix::clear() leave row and column 0 as used. After applying this fix, I can't reproduce the assertion failure @mattsc reported or the hang @GregoryLundberg reported. Those problems were likely caused by the memory corruption.
This commit is contained in:
parent
0bbcd4055e
commit
9f379b96e3
1 changed files with 7 additions and 0 deletions
|
@ -835,6 +835,13 @@ void prob_matrix::clear()
|
|||
|
||||
used_rows_[p].clear();
|
||||
used_cols_[p].clear();
|
||||
|
||||
/* Row and column 0 are always considered to be used.
|
||||
Functions like merge_col() access *used_rows_[plane].begin() without checking if there are
|
||||
any used rows: thus, ensuring that there are used rows and columns is necessary to avoid
|
||||
memory corruption. */
|
||||
used_rows_[p].insert(0u);
|
||||
used_cols_[p].insert(0u);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue