Advertisement

Bug hunt

Started by August 18, 2000 01:51 PM
2 comments, last by Aldacron 24 years, 4 months ago
For three days this has had me stumped. My game was running fine (nearly complete) until I recompiled after adding some sound effects. Now I have a page fault with previously working code. Here we go: I have a char** variable called "grid". It is allocated based on a variable called "difficulty". I know the problem lies not in the allocation or deallocation code, because it worked fine before. The problem is, if I allocate grid as a 4x4 or 6x6 array, I get the page fault. Debugging shows it comes when I call free (I''m using straight C in VC++ 6, BTW) on the last 1x4 or 1x6 element in the array. Debugging gives me something like: Debug Error: DAMAGE: after Normal block (#58) at That''s with the 4x4. With the 6x6 it''s #60 instead of #58. Now, if I allocate an 8x8 array, no problem. Everything works like it should. I consulted MSDN and couldn''t find anything specific, but I''m assuming after reading about _free_dbg and the debuggers mempory management, that I''m somehow writing past the upper bounds of the allocated memory. But that leaves me with several questions. The code is the same no matter what the array size, so why doesn''t it do the same for an 8x8 array? Also, I changed nothing in the original code when I added the sound effects. I just added some code to load and play a few waves via my library. So why did this suddenly crap out when I recompiled? I thought I could squash any bug with a day or two away from a project, but this one has me beat. Any ideas, clues or suggestions are greatly appreciated. This is my puzzle contest project. I had planned to finish by Sunday and move on to something else, but so much for that.
It sounds like you have free''d the array of pointers, and then dereferenced them to free the rows. This is a nasal deamon, another guess is that the sound code is grabbing the newly free''d memory before you dereference, and thats why it''s breaking now. It was likely always broken, it just happened to work.

Going out on a limb here, you are using this so you can say grid[x][y] somewhere aren''t you? What is the fasination with this construct? Everyone is bending over backwards to avoid saying grid[y*width+x] WHY??????? How do you suppose the compiler does grid[x][y]? if you have char[8][8] the comiler can resolve this to grid[y<<3+x], so that''s faster. But with a dynamic array you have to dereference, fetch, dereference, fetch to get your value. You also have lost locality of reference and wasted Y pointers. C++ people also do vector < vector < T > > all the time. Then they use a fixed width and height.
Advertisement
I always thought they should just let you overload the [] operator with more than one parameter, giving you a BASIC-/Pascal-like reference (ie, grid[8,4], space[50,1,24], etc.). Not that I''m much for BASIC or Pascal anymore, but I always found that much easier than grid[8][4]. Usually, I just make an object with an inline member function Index(int x,int y,etc.) that does the same thing. *shrug*

Here''s something for some abstract physics: char& operator[](int x, ...);
quote: Original post by SkyDruid

I always thought they should just let you overload the [] operator with more than one parameter, giving you a BASIC-/Pascal-like reference (ie, grid[8,4], space[50,1,24], etc.). Not that I''m much for BASIC or Pascal anymore, but I always found that much easier than grid[8][4]. Usually, I just make an object with an inline member function Index(int x,int y,etc.) that does the same thing. *shrug*

Here''s something for some abstract physics: char& operator[](int x, ...);


Yeah, that would be the way to go, the let you call it with strings for assoiative objects, so your already abusing the syntax. One trick is to have an index class, or a heiarchy with some classes forceing powers of 2. Then you define () and at() where at does bounds checking and throws exceptions. Each just returns size_t = wh*Z+w*Y+X, with shifts in the pow2 variant. It s then trivial to either compose a class with a data pointer and index, or use it as a utility class. Good tradeoff between programmer/program optomisations.

grid[CIndex2(8,8)(3,4)] might look horrid, but it actually compiles fairly tight. grid[I(3,4)] is beter and it becomes easy to write functions of the form f(const Index2 &I, char *data); It sometimes makes sense to break the expected encapsulation, even though we have no assurance that *data points to a region of the correct size.

This topic is closed to new replies.

Advertisement