I'm writing a win console program that creates 100 binary search trees, each consisting of 500 nodes that each hold an integer between 0 and 500.
The trees are getting their 500 integers from an instance of a class intlist, a list that holds the integers 0..500 in a random order.
i'm using pointers to create instances of the trees, cuz i tried using an array, but for some reason the program ended up adding the new nodes to the existing tree... that was solved by using pointers, though.
the remaining problem is: it crashes after created 3 or 4 trees! okay, so i have a faulty program, big deal.. I debugged, works fine!
every time i debug, it works fine, and when i'm not debugging, it crashes.
i'm using dev-cpp under windows vista.
here's the code for my main:
const int TREE_AMOUNT = 100;
void filltree(intlist mylist, bst & mytree, int a)
int c = 0;
for(c; c <= NODE_AMOUNT; c++)
// cout << a << " ";
cout << "Tree created! Internal Path Length: " << mytree.ipl << endl;
int a = 0,c=0;
for(a; a<=TREE_AMOUNT; a++)
mylist = new intlist;
mytree = new bst;
filltree((*mylist), (*mytree), a);
cin >> a;
Can anyone tell me what's going on here? this is rather frustrating.. :P
No, there is no difference. Having said that, no C++ programmer writes pointer accesses the second way. You won't even find a decent book that writes a normal pointer access using the latter syntax. So what your code was doing flies in the face of what any decent C++ programmer does.
Can you please explain how a program can be working in debug if it doesn't run outside debug?
If you have an uninitialized variable, an out-of-bounds memory access, or something similar, the behaviour of a program is undefined. It could work, it could crash, it could work some time but not all the time, it could work on your machine and fail on another machine, etc.
Here in your code is a perfect example:
const int NODE_AMOUNT = 6;
for(c; c <= NODE_AMOUNT; c++)
cout << content[c] << " : ";
So let me ask you -- what happens when c is equal to NODE_AMOUNT? The content[c] is an illegal memory access, as the content array can only be accessed from 0 to 5.
That is basically what's wrong with your entire program. Arrays start at 0, not at 1. However your entire code starts counting arrays at 1. This is a recipe for disaster. Access your arrays naturally, and that is starting at 0 and ending at index-1.
You're doing this or similar several times
newnode = root;
newnode = new node;
What's the point? You assign a value to newnode then overwrite it immediately.
Debug and release builds aren't exactly the same. Results of using memory improperly are undefined. Your program may crash, may act strangely, or may appear to act normally. It's obviously crashing in release and one of the other two in debug. You can add debug information to a release build and run the release build in the debugger to help find problems like that.
However, i still don't get how it could run fine in debug mode, and fail outside debug.
Again, undefined behavior. This concept is something you must understand.
I'll repeat again --
when your program overwrites memory, does an illegal array access, does an illegal pointer access, etc. the behaviour of that program is undefined. You see it there yourself -- so there is no need now to be surprised.
Have you ever heard of programs working perfectly at the company, and then when you bring that program to a client, it bombs out? Or a program that works perfectly at the shop, and then when a customer buys it, they are having problems?
If the original program is written in C++, all of these scenarios can be due to bugs in the program that were "hidden" when run on one machine or environment or set of compiler settings, but is exposed when running on a different machine, environment, different compiler settings, etc.
I can't imagine this being coincidental, as i ran it about twenty times in debug and 20 times outside.
You could run it 1,000 times in the debugger, and have it work 999 times outside the debugger. It's that 1 time it doesn't work that proves that your program has a bug.
While all this is great on a theory level, I'll give you some information that may actually help you in practice.
There are many ways in which debug builds differ from release builds, but two in particular I find can frequently lead to works-debug-fails-release errors:
1) Uninitialized variables. If you declare an int variable but don't give it a starting value, in debug mode its value will be automatically set to 0, which is usually what is intended. This will not happen in release builds: its value may be any arbitrary number before you assign something to it. And if you try to use it before doing that (for instance, incrementing it as a counter), who knows what might happen.
2) Dynamic memory allocation. In debug builds, dynamic arrays are allocated *more* space than you ask for, and those excess bytes are filled with a known byte pattern (like 0xcdcdcdcdcdcd). The idea is that if you overwrite the bounds of the array, then a portion of the program later (usually the delete operator) can detect it because the byte pattern will be altered. This would give you the infamous "heap corruption detected" run-time error. When you move to a release build, there are no such excess bytes allocated, and overwriting an array can then modify data structures vital to the operation of your program.