• Advertisement
Sign in to follow this  

Memory overruns with std::vector?

This topic is 3960 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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-&gt;myDeals[res].size()));
  myDeals[res].push_back(d);
  log(stringify(this) + " Line b of registerBid; tester size " + stringify(tester-&gt;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.

Share this post


Link to post
Share on other sites
Advertisement
reserve() is not resize().

Share this post


Link to post
Share on other sites
Before examining your code further, let me ask this:
myDeals[res].push_back(d);
Are you sure that res < myDeals.size()? If not, you might consider using at() instead of operator[](), as it will throw an exception (IIRC) if the index is out of range.

My thought here (which might be totally off base), is that where you have:
myDeals.reserve(Resource::numResources);
You actually mean:
myDeals.resize(Resource::numResources);
resize() and reserve() are often confused with one another, but they do fundamentally different things.

[So very slow...]

Share this post


Link to post
Share on other sites
Log/assert:
myDeals.size()
and
myDeals.size() > res

researve builds space of non-initialized data.

resize both reserves and initializes the data.

You reserve if and only if you don't want to initialize the data now, and can get around to doing it later, and you know how much data you will have, and you would rather spend the time reallocating once now then doing it "on the fly" later.

Share this post


Link to post
Share on other sites
Ahhhh... *Lights up with comprehension*

Thank you, gentlemen, that solved my problem. Now it runs beautifully. Ratings all around. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement