From b0045fa357e2a504e406b89b663c5594536c559f Mon Sep 17 00:00:00 2001 From: Arseniy Shestakov Date: Tue, 16 Aug 2016 15:47:21 +0300 Subject: [PATCH] Fix TurnInfo memory leaks --- lib/CPathfinder.cpp | 18 ++++++++++++++++++ lib/mapObjects/CGHeroInstance.cpp | 14 ++++++++++++++ server/CGameHandler.cpp | 5 ++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/CPathfinder.cpp b/lib/CPathfinder.cpp index b96203055..a75e94ee4 100644 --- a/lib/CPathfinder.cpp +++ b/lib/CPathfinder.cpp @@ -1031,8 +1031,12 @@ int CPathfinderHelper::getMovementCost(const CGHeroInstance * h, const int3 & sr if(src == dst) //same tile return 0; + bool localTi = false; if(!ti) + { + localTi = true; ti = new TurnInfo(h); + } if(ct == nullptr || dt == nullptr) { @@ -1068,7 +1072,12 @@ int CPathfinderHelper::getMovementCost(const CGHeroInstance * h, const int3 & sr ret *= 1.414213; //diagonal move costs too much but normal move is possible - allow diagonal move for remaining move points if(ret > remainingMovePoints && remainingMovePoints >= old) + { + if(localTi) + delete ti; + return remainingMovePoints; + } } /// TODO: This part need rework in order to work properly with flying and water walking @@ -1083,10 +1092,19 @@ int CPathfinderHelper::getMovementCost(const CGHeroInstance * h, const int3 & sr { int fcost = getMovementCost(h, dst, elem, nullptr, nullptr, left, ti, false); if(fcost <= left) + { + if(localTi) + delete ti; + return ret; + } } ret = remainingMovePoints; } + + if(localTi) + delete ti; + return ret; } diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index be22b9ca9..62bacd9d0 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -187,8 +187,12 @@ bool CGHeroInstance::canLearnSkill() const int CGHeroInstance::maxMovePoints(bool onLand, const TurnInfo * ti) const { + bool localTi = false; if(!ti) + { + localTi = true; ti = new TurnInfo(this); + } int base; @@ -213,6 +217,9 @@ int CGHeroInstance::maxMovePoints(bool onLand, const TurnInfo * ti) const const int subtype = onLand ? SecondarySkill::LOGISTICS : SecondarySkill::NAVIGATION; const double modifier = ti->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, subtype) / 100.0; + if(localTi) + delete ti; + return int(base* (1+modifier)) + bonus; } @@ -1199,14 +1206,21 @@ CBonusSystemNode * CGHeroInstance::whereShouldBeAttached(CGameState *gs) int CGHeroInstance::movementPointsAfterEmbark(int MPsBefore, int basicCost, bool disembark /*= false*/, const TurnInfo * ti) const { + bool localTi = false; if(!ti) + { + localTi = true; ti = new TurnInfo(this); + } int mp1 = ti->getMaxMovePoints(disembark ? EPathfindingLayer::LAND : EPathfindingLayer::SAIL); int mp2 = ti->getMaxMovePoints(disembark ? EPathfindingLayer::SAIL : EPathfindingLayer::LAND); if(ti->hasBonusOfType(Bonus::FREE_SHIP_BOARDING)) return (MPsBefore - basicCost) * static_cast(mp1) / mp2; + if(localTi) + delete ti; + return 0; //take all MPs otherwise } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index fc54e995a..d3c8bb072 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1539,8 +1539,10 @@ void CGameHandler::newTurn() NewTurn::Hero hth; hth.id = h->id; + auto ti = new TurnInfo(h, 1); // TODO: this code executed when bonuses of previous day not yet updated (this happen in NewTurn::applyGs). See issue 2356 - hth.move = h->maxMovePoints(gs->map->getTile(h->getPosition(false)).terType != ETerrainType::WATER, new TurnInfo(h, 1)); + hth.move = h->maxMovePoints(gs->map->getTile(h->getPosition(false)).terType != ETerrainType::WATER, ti); + delete ti; hth.mana = h->getManaNewTurn(); n.heroes.insert(hth); @@ -1996,6 +1998,7 @@ bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 teleporting, bo const bool canFly = ti->hasBonusOfType(Bonus::FLYING_MOVEMENT); const bool canWalkOnSea = ti->hasBonusOfType(Bonus::WATER_WALKING); const int cost = CPathfinderHelper::getMovementCost(h, h->getPosition(), hmpos, nullptr, nullptr, h->movement, ti); + delete ti; //it's a rock or blocked and not visitable tile //OR hero is on land and dest is water and (there is not present only one object - boat)