Weirdo C++ problem (dynamic memory, it seems)
Moderator: Thanas
- Dooey Jo
- Sith Devotee
- Posts: 3127
- Joined: 2002-08-09 01:09pm
- Location: The land beyond the forest; Sweden.
- Contact:
Weirdo C++ problem (dynamic memory, it seems)
So I have this code, which creates a few inherited classes (which I will henceforth call "sprites") and adds their pointers to my sprite rendering vector, and a vector to keep track of which sprites were created (these sprites are sort of parented to another class, obviously I don't keep all sprites in two vectors...) at one point, and at a later time, some more sprites may be created, or some of them may be removed. Now, all of this would work fine, if it wasn't for one small issue, which is the weirdo bug:
Sometimes a newly created sprite has the same address as an old sprite, which has not yet been deleted (and one time, I think a new one had the same address as a previously deleted sprite, but it crashed anyway). Obviously this is very bad, and even more annoying is that this does not seem to happen in debug mode. I was only able to pinpoint the strange crashes that happened by using low-tech error logging files (and it doesn't crash when the sprites are created, or even rendered, only later when I try to use a sub-class method, so maybe it's only able to partially create the offending classes, though the log files suggests otherwise)... I do exception handling, tests for NULL pointers, but to no avail. "new" seems to work as it should, only something goes horribly wrong.
Does anyone have any idea as to what might cause this? It's not even a compiler issue either, it happens on both GCC and Visual Studio, so my code must be broken somehow. I just don't know where to look (and I've checked the constructors and destructors, and just about everything I can think of (including rewriting so that it uses a linked list instead of a vector, and about a million other things), they really do seem to be working like they usually do).
Help, please.
Sometimes a newly created sprite has the same address as an old sprite, which has not yet been deleted (and one time, I think a new one had the same address as a previously deleted sprite, but it crashed anyway). Obviously this is very bad, and even more annoying is that this does not seem to happen in debug mode. I was only able to pinpoint the strange crashes that happened by using low-tech error logging files (and it doesn't crash when the sprites are created, or even rendered, only later when I try to use a sub-class method, so maybe it's only able to partially create the offending classes, though the log files suggests otherwise)... I do exception handling, tests for NULL pointers, but to no avail. "new" seems to work as it should, only something goes horribly wrong.
Does anyone have any idea as to what might cause this? It's not even a compiler issue either, it happens on both GCC and Visual Studio, so my code must be broken somehow. I just don't know where to look (and I've checked the constructors and destructors, and just about everything I can think of (including rewriting so that it uses a linked list instead of a vector, and about a million other things), they really do seem to be working like they usually do).
Help, please.
"Nippon ichi, bitches! Boing-boing."
Mai smote the demonic fires of heck...
Faker Ninjas invented ninjitsu
Mai smote the demonic fires of heck...
Faker Ninjas invented ninjitsu
-
- Jedi Council Member
- Posts: 1571
- Joined: 2002-07-13 12:56pm
Sounds like you've got a buffer overflow sonewhere to me. Bizarre, intermittant problems that don't occur in debug mode? Yeah, that sounds like a buffer overflow alright. Extra memory is generally allocated as guards around newed arrays and such in debug mode which makes finding off by one errors ever so much fun.
- Darth Paul
- Sith Apprentice
- Posts: 52
- Joined: 2002-08-22 11:44pm
- Location: Canada
Debugging the Release build is a good suggestion to find the crash point - try turning off all optimizations and inlining in the release build, as this will help the debugger report your variable values better, or post some code if you can. In my experience, by far the most common source of debug/release differences is uninitialized (or un-reset) variables, since the debugger will initialize values to zero, which your code may be catching in debug when checking for NULL, etc, but it's really just guessing without seeing real code.
- Dooey Jo
- Sith Devotee
- Posts: 3127
- Joined: 2002-08-09 01:09pm
- Location: The land beyond the forest; Sweden.
- Contact:
Thanks guys, I've solved it now. I always had a feeling it would turn out to be something retardedly simple, and that I would discover it three seconds after posting...
Both Mad and Crazy_Vasey were sort of correct. What was happening was that some sprites got destructed early because of an error in a slightly related piece of code, and the vector that kept track of them didn't know this (but the rendering vector did, which was why it didn't crash immediately), so yeah... I'm going to be ashamed of myself for a year now...
But thanks again everyone!
Actually, I have another interesting error that only happens in Visual Studio. This one isn't critical, since I can fix it. I just want to know what's going on. Here's the code:
I have to use the (here commented out) variable "value" instead of "types[p]" otherwise it crashes the second time it is used, ie in "data.newType = types[p]". Isn't that interesting...
Both Mad and Crazy_Vasey were sort of correct. What was happening was that some sprites got destructed early because of an error in a slightly related piece of code, and the vector that kept track of them didn't know this (but the rendering vector did, which was why it didn't crash immediately), so yeah... I'm going to be ashamed of myself for a year now...
But thanks again everyone!
Beowulf wrote:You can still debug with it in release config in Visual Studio. It just doesn't work quite as well.
Yes, this was what I meant by the debug "mode" as opposed to a debug build.Destructionator XIII wrote:Ditto for g++ and gdb. Try g++ -ggdb -O2 for optimizations and debug info at the same time.
Actually, I have another interesting error that only happens in Visual Studio. This one isn't critical, since I can fix it. I just want to know what's going on. Here's the code:
Code: Select all
void RunningStateMayor::ImgButtonClick(GUIImage* img) {
if (mCurrArea == NULL) return; // An area must be set
unsigned int p=0; // Get the index of the clicked image in the list
for (GUIObjectList::iterator it=mImgButtons.begin();
*it != img;
it++,p++) {
if (it==mImgButtons.end()) { // Apparently, this image is not in the list
return; // And that should not happen (we could also throw here)
}
}
// Get the list of types the current area can be transformed into
const vector<int>& types = mCurrArea->GetInfo().transform;
if (!types.empty() && p < types.size()) { // Make sure the index is valid
// Visual Studio likes to crash if we use types[p] at other places
// Why? I have no bloody idea...
// int value = types[p];
mCurrArea->Change(mMapAreaFactory.getAreaInfo(types[p])); // Change the area
// Set up data to send over the network
NetAreaChange data("");
data.newType = types[p];
int i=0;
for (list<MapArea>::iterator it = mMapAreas.begin();
&(*it) != mCurrArea; it++,i++) {
if (it == mMapAreas.end()) {
return; // Unusual behaviour (throw instead?)
}
}
data.areaIndex = i;
objects->net.sendData(&data);
}
[snip some more code]
}
"Nippon ichi, bitches! Boing-boing."
Mai smote the demonic fires of heck...
Faker Ninjas invented ninjitsu
Mai smote the demonic fires of heck...
Faker Ninjas invented ninjitsu
- Dooey Jo
- Sith Devotee
- Posts: 3127
- Joined: 2002-08-09 01:09pm
- Location: The land beyond the forest; Sweden.
- Contact:
Yeah, it's really strange. The "Change()" function is working with a reference to a "mapAreaInfo" struct, but not only should that not affect the index or the vector, it is also const, and if it did change anything, the compiler would say so...Destructionator XIII wrote:Well, maybe it is getting confused since you change that thing in mCurrArea, and you are working with a reference to something inside it? If that change touches something in there, it might b0rk the const reference.
I'm just taking a random stab; I really don't know.
"Nippon ichi, bitches! Boing-boing."
Mai smote the demonic fires of heck...
Faker Ninjas invented ninjitsu
Mai smote the demonic fires of heck...
Faker Ninjas invented ninjitsu
- Durandal
- Bile-Driven Hate Machine
- Posts: 17927
- Joined: 2002-07-03 06:26pm
- Location: Silicon Valley, CA
- Contact:
Does your indexing operator implementation change the object's state in any way? Have you tried changing it to return a compile-time value to see if it gives you the same problem?
Damien Sorresso
"Ever see what them computa bitchez do to numbas? It ain't natural. Numbas ain't supposed to be code, they supposed to quantify shit."
- The Onion
"Ever see what them computa bitchez do to numbas? It ain't natural. Numbas ain't supposed to be code, they supposed to quantify shit."
- The Onion
- Dooey Jo
- Sith Devotee
- Posts: 3127
- Joined: 2002-08-09 01:09pm
- Location: The land beyond the forest; Sweden.
- Contact:
Well it's an STL vector, and since it is const, it really shouldn't. Though I've heard that VS has a history of weird STL implementations (even though this is VS 8)...Durandal wrote:Does your indexing operator implementation change the object's state in any way? Have you tried changing it to return a compile-time value to see if it gives you the same problem?
"Nippon ichi, bitches! Boing-boing."
Mai smote the demonic fires of heck...
Faker Ninjas invented ninjitsu
Mai smote the demonic fires of heck...
Faker Ninjas invented ninjitsu