Stupid Code…
Here’s a little C++ quiz for you. What’s wrong with this code?
struct Foo
{
std::vector<Bar> bars;
createBar(int x);
};
void Foo::createBar(int x)
{
Bar bar;
bars.push_back(bar);
someOtherThing[x].pointerToBar = &bars.back();
}
{
createBar(1);
createBar(2);
createBar(3);
}
[On that note, does anyone know a good C++ code renderer for WordPress? I apologize for the formatting.]
What’s happening in the code is that you call createBar() to create a series of bars. These bars get stored in a vector of Bars, which is fine.
someOtherThing is using that vector to store a collection of pointers to those Bars. Seems innocent enough.
In fact, if you later did something like:
someOtherThing[3].pointerToBar->someBarThing();
It would work perfectly fine.
But if you did:
someOtherThing[1].pointerToBar->someBarThing();
You’d segfault. Why is the 1st Bar suddenly invalid?
The problem is that someOtherThing is getting pointers to Bars that exist in the vector at that time they are requested. The next time a Bar gets added to the vector, however, might require the vector to be resized, and so while the Bars in the vector are all there, they basically moved house, so the pointers you stored while creating them are no longer valid.
And that is why I took so long to figure out why my Courier selection code would crash on only some of the Couriers, and that is why I probably won’t get an entry submitted for Ludum Dare #20.
2 hours left to go. I’m going to get dinner.
In the meantime, here’s a screenshot showing the couriers on the left and the enemy agents on the right.
I now have the ability to select the courier you want to move once I moved the “store pointers” work into a batch operation. I thought not using pointers in the first place would save me headaches, but I guess I should have just new-ed up the Couriers in the first place. B-(
