浏览代码

Fix TurnInfo memory leaks

Arseniy Shestakov 9 年之前
父节点
当前提交
b0045fa357
共有 3 个文件被更改,包括 36 次插入1 次删除
  1. 18 0
      lib/CPathfinder.cpp
  2. 14 0
      lib/mapObjects/CGHeroInstance.cpp
  3. 4 1
      server/CGameHandler.cpp

+ 18 - 0
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;
 }
 

+ 14 - 0
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<double>(mp1) / mp2;
 
+	if(localTi)
+		delete ti;
+
 	return 0; //take all MPs otherwise
 }
 

+ 4 - 1
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)