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-(
4 replies on “LD20: Stupid Code…”
I use the Google Syntax Highlighter, but here’s a few options:
http://speckyboy.com/2009/02/19/12-wordpress-plugins-to-display-and-highlight-code-within-your-blog/
keep going man, hopefully you get an entry in time! #cross-fingers
One of the other options which I’ve been using is this: http://wordpress.org/extend/plugins/wp-syntax/
Reserve the number you need before accessing the container, then they want shift in memory. Wrap anything that adds to the container and assert if you go beyond the reserved size.
Better off dynamically allocating the items in the container, then it doesn’t matter if the container shifts its pointers (they’re just pointers). Anyway, you have to do it this way if the data is polymorphic or remotely complicated (otherwise it starts getting copied when you push it in which can make things complicated).
Yeah, I see more than ever that pointers make things simpler if I am dealing with objects that need their state to change. I suppose I could go through the convoluted steps of copying the original, deleting the original, updating the copy, and replacing the original with the copy, but again, pointers makes this dead simple.