At least, that's all I can think of. I am working on some economics code, and I have a class which needs to keep track of several possible sources for each of several possible resources. It therefore contains this:
std::vector<std::vector<Deal*> > myDeals;
(...)
myDeals.reserve(Resource::numResources);
where Deal is a helper struct containing the seller, the price, and the amount on offer. Now, at one point my buyer class goes through a list of all possible sellers, storing those that it has access to and can afford to buy from at the current price. It also registers that deal with the seller.
So, now I come to testing this code. I have two buyers, which are referred to as 'ProvinceA' and 'ProvinceB'. They want to buy labour, for which there are two sellers, 'PopA' and 'PopB'. ProvinceA goes first, and registers first with PopA, increasing the size() of PopA's myDeals[labourIndex] to 1. That's just as it should be. Then it tries to register with PopB, and Something Weird happens. Here is the code for registering with a seller:
void Actor::registerBid (unsigned int res, Deal* d) {
assert(d);
log(stringify(this) + " Line a of registerBid; tester size " + stringify(tester->myDeals[res].size()));
myDeals[res].push_back(d);
log(stringify(this) + " Line b of registerBid; tester size " + stringify(tester->myDeals[res].size()));
}
Some debugging included, as you'll note. Here 'tester' is a global pointer to PopA. Now here is the output:
PopB Line a of registerBid; tester size 1
PopB Line b of registerBid; tester size 4294966313
So, the code arrives in registerBid and finds that PopA has one deal registered, just as it should be. It pushes the new Deal onto PopB's vector - and suddenly calling PopA's vector's size() method gives nonsensical results. It seems to me that this is a symptom of a buffer overrun or something similar - at any rate it seems clear that PopA->myDeals[res] has got clobbered - but I don't understand how that can happen with this code. Is there some pitfall involved with using vectors of vectors?
Not sure if it's relevant, but I'm using gcc 3.2.3 on Linux24SL3.
To win one hundred victories in one hundred battles is not the acme of skill. To subdue the enemy without fighting is the acme of skill.