Strange problem with new Civ4Col mod starting

Good it working perfectly. Thanks! :)

EDIT: The debugging of the crash I was having is directing me here (in CvCity.h):

Code:
#ifdef _USRDLL
	inline PlayerTypes getOwnerINLINE() const
	{
		return m_eOwner;
	}
#endif

Does anyone have a general idea of what it might be causing this? (also - this happens at exactly turn 52, and when I play with one human player - no AIs, it doesn't occur)

I'm thinking there might be a common mistake that I'm missing...
 
It seems you're trying to access a city that is no longer valid or more likely through a NULL pointer. What is the code that leads to this being called?

I would bet that VS 2010 will work just as well as VS 2008 and VS 2005 before it. Since the VS tool isn't doing any compilation there are no built-in libs causing clashes. What you're getting with the more modern tools are better code navigation (yay) and prettier toolbars (whatever).
 
It seems you're trying to access a city that is no longer valid or more likely through a NULL pointer. What is the code that leads to this being called?

It is the game's original getOwnerINLINE code, so it is accessed by a lot of things; I keep a lot of backups, so I was able to trace to which version change of my mod the crash started occurring; I tried commenting out multiple segments of the added code between the versions, but so far haven't been able to track down what exactly is causing this. I imagine from what you said that it probably is code outside CvCity.cpp trying to access the getOwnerINLINE() function of a no-longer existing city that is causing this? Also, what did you mean by a NULL pointer?

EDIT: I forgot to say, I had tested in a scenario with only two civilizations and it still crashed in turn 52.

EDIT2: As a second note, the most of the changes I made between versions involved multiplying (from the XML numbers) and dividing (to the numbers that would actually show up in game) numbers by 100, to account for decimals and centesimals in the game mechanics. Maybe that made me go over MAX_INT somewhere?
 
You mean it crashes on turn 52 each time you start a new game with a new map and different players??? That's a very good clue, but I have no idea what it means.

A pointer in C++ is the memory address, and many places in the DLL pass around a "CvCity*" which is a pointer to a CvCity object. NULL is just a constant for 0, so a null pointer means a pointer that has not been assigned a real memory address. Address zero is not valid in most processors.

Are you attaching the VS debugger to Civ4 before the crash? If so, it should give you more information than just "crash" when it dies. Also you should be able to walk backwards through the call chain that lead to the crash. That's what I'm talking about what is calling it--not what functions might ever call it but what function is actually calling it that time.
 
You mean it crashes on turn 52 each time you start a new game with a new map and different players??? That's a very good clue, but I have no idea what it means.

The mod is scenario specific, so it's the same map; I have tried with different players though. Strangely, it's always on the exact same turn.

A pointer in C++ is the memory address, and many places in the DLL pass around a "CvCity*" which is a pointer to a CvCity object. NULL is just a constant for 0, so a null pointer means a pointer that has not been assigned a real memory address. Address zero is not valid in most processors.

Are you attaching the VS debugger to Civ4 before the crash? If so, it should give you more information than just "crash" when it dies. Also you should be able to walk backwards through the call chain that lead to the crash. That's what I'm talking about what is calling it--not what functions might ever call it but what function is actually calling it that time.

I didn't know I could do that! That helps a lot :)

EDIT: I think I have found it! This is probably what is causing the problem:

Code:
				CvCity* pBestYieldCity = NULL;
				int iBestCityValue = 0;

				int iLoop;
				CvCity* pLoopCity;
				for(pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
				{
					for (int iProfession = 0; iProfession < GC.getNumProfessionInfos(); ++iProfession)
					{
						CvProfessionInfo& kLoopProfession = GC.getProfessionInfo((ProfessionTypes)iProfession);
//						if (kLoopProfession.getYieldConsumed() == eLoopYield)
//MultipleYieldsConsumed by Aymerick
 						if (kLoopProfession.getYieldsConsumed(0) == eLoopYield)
//MultipleYieldsConsumed End
						{
							int iValue = pLoopCity->getProfessionOutput((ProfessionTypes)iProfession, NULL);
							if (iValue > 0)
							{
								iValue *= 100;
								iValue += pLoopCity->getPopulation();
								if (iValue > iBestCityValue)
								{
									iBestCityValue = iValue;
									pBestYieldCity = pLoopCity;
								}
							}
						}
					}
				}
				yield_dests[eLoopYield] = pBestYieldCity;
[COLOR="Red"]				if (GC.getGameINLINE().getGameTurn() > 50)[/COLOR]
				{
					pBestYieldCity->setMaintainLevel(eLoopYield, pBestYieldCity->getMaxYieldCapacity() / 2);
				}

It functions only if getGameTurn() is higher than 50 (and thus, in the doTurn() of the first turn after 50, turn 51, it will cause the crash, while already having changed the turn shown on screen to 52!), and in the loop, if iValue isn't higher than 0, no valid pBestYieldCity is set, and since it doesn't check if it isn't NULL later on, it could be calling a non-existent city. I'll add a check for it not being NULL and see if it solves the problem :D

EDIT2: That fixed the problem, I can barely believe it! Thanks a whole lot EmperorFool, deanej and Afforess! :goodjob: And thanks to KJ Jansson too for bringing up this discussion :)
 
Back
Top Bottom