I'm currently struggling to debug the following code part. I'm using VS2015 community edition on windows 10.
[(BR)] is a breakpoint
The following is a (slimmed down) version of my code. I basically have nested for loops that extract all points (X&Y coordinates) from all gameObjects.
As you can see I set two breakpoints.
I hit the debug button and it stops at the first breakpoint - success. Important local variable counterVertices is zero. Great as well.
Then I hit continue. It goes TO THE SAME BREAKPOINT THREE TIMES.
Then I get to the second breakpoint. counterVertices shows zero. Why?
int counterVertices = 0;
int counterIndices = 0;
int beginningOfPolygon = 0;
//GetData
for (auto& it : this->gameObjects) { //Iterate over all gameObjects
beginningOfPolygon = counterIndices;
for (int i = 0; i < it->getOutline().getNumber(); i++) { //Iterate over all points of the gameObject
[(BR)]this->vertices[counterVertices] = it->getRenderPoint(i).x;
counterVertices++;
this->vertices[counterVertices] = it->getRenderPoint(i).y;
counterVertices++;
[(BR)]if (this->vertices[counterVertices-2] == this->vertices[counterVertices-1] && this->vertices[counterVertices-1] == 0.0f) {
cout << "A point on 0/0." << endl;
}
this->vertices[counterVertices] = 0.0f;
counterVertices++;
//Add Line to draw
this->indices[counterIndices * 2] = counterIndices;
this->indices[(counterIndices * 2) + 1] = counterIndices + 1;
counterIndices++;
}
this->indices[(counterIndices * 2) - 1] = beginningOfPolygon;
}
I'm completely lost as this isn't even the problem I wanted to solve in the first place but rather got stuck on trying to figure on my original issue.
Thanks already for your time
PS: I have screenshots of the whole thing and the process is recreatable. I can clean and rebuild the solution, restart and do a backflip. Debugging behaviour doesn't change.
PPS: The program behaves/works in a way that suggest that counterVertices is increased correctly but the debugger information contradicts that.
Make sure you have optimizations turned off. Optimizations can really make it hard to debug, as values will be held in registers and not stored until it needs to. And code flow can be very unintuitive.
Related
So I wanted to write a program which prints out a pyramid made out of "O", whose height is given by user input.
#include <stdio.h>
int main()
{
int n, i, j, k;
scanf_s("%d", &n);
{
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n - i; j++)
{
printf(" ");
}
for (k = 1; k <= 2 * i - 1; k = k + 1);
{
printf("O");
}
printf("\n");
}
return 0;
}
}
I'm a complete beginner, so if you have any advice, please do offer it. Anyways, I tried running it on a compiler on Android; seemed to work, printed out the pyramid.
Tried it on Microsoft Visual Studio. The command line opens, but after I put in the number and press "enter", the whole window just closes without giving me anything. How do I prevent this? Programs that don't need user input seem to run just fine.
For your described problem: Preventing console window from closing on Visual Studio C/C++ Console application
For your code, there seems to be a mistake, and currently your code will not produce a pyramid, but a slash of O. To solve this problem:
for (k = 1; k <= 2 * i - 1; k = k + 1); remove the ; from this line. Why this solved the problem?
When there is a ; after the loop, it means that the loop does nothing, and then the next three lines are:
{
printf("O");
}
Which means that there are only a single O prints out, instead of printing it in a loop.
Apart from the semicolon after the for (k = 1... loop, you have no bug in this code; if Visual Studio closes, the issue is with that program. (It could well just be closing because the program has finished execution, but I don't know that program).
Since you write that you are a complete beginner and you would appreciate advice, I'll offer some stylistic comments. But these are just comments on how I would do things differently if I were you, I am not saying that what you have is wrong.
Single-letter variable names: these will bite you. It is really easy to mix up i, j, and k since they are all kind of meaningless indexes. When your programs become more complex you will be happy to have meaningful variable names. Also, if you are trying to locate instances of a variable, searching for 'i' is a lot harder than searching for "spaces" or "spc"
Code block under scanf_s(): There is no reason to have this code inside a block--all that does is shift the internal code one tab right. Screenspace is precious.
You will likely find it more useful to iterate from 0 than from 1, as you will be using your iterator variable as an array index a whole lot. Getting into the habit of writing your loops as for (dex = 0 ; dex < max_val ; dex++) will serve you well. Note well that the comparison is "dex < max_val" and not "dex <= max_val"
The "k = k + 1" seems bad to me--people reading your code will need to stop and try to figure out why it's not just "k++" which what people are expecting and what you use in the other two loops. (And even for incrementing-by-more-than-one I'd expect something like "k += 2" not "k = k + 2")
Once console application returns from main method, the associated console window closes automatically. For Windows OS add a system("pause"); before your return 0; statement. For platform independent solution you can just show a prompt to user and wait for a key press before returning from main. Any character remaining in input buffer (enter from scanf in this case) must be cleared.
int main()
{
.........
.........
//clear input buffer
int d;
while ((d = getchar()) != '\n' && d != EOF) { }
printf("Press ENTER key to Continue\n");
getchar();
return 0;
}
You should include conio.h header file in your program and then simply place getch(); after your program's last cout statement.
I think that this would help the window from closing
it worked for me ;)
Put a cin command(C++) or a C equivalent at the very end just before return 0;, so it wont close. :>
Eg:
.
.
.
.
int control; cin>>control;
return 0;
}
I'm having trouble understanding why my return data is garbage when I don't use debug to print it out and is fine when I do print it out. I am using C++ make_tuple and tie on the other end for float values. If I don't include enough info let me know!
I have tried checking for uninitialized data by printing out my functions. I also use this exact same code in other parts of the program with no issue.
To give a background of what this program is. I am reading an adc value getting the max value (with error checking) and then sending it for a pass-fail for the system and display to the user. I can work around this in a few ways but I am mostly just curious about this bug.
std::tuple<float,float> hardware_control::hv_check()
{
float hv_filtered_max = 0;
float hv_filtered_avg = 0;
int samples = HV_SAMPLES;
float hv_adc_read[samples];
int non_zero_samples = 0;
int i = 0;
int loops = 0;
//here we will take the a number of samples, average and find the max
while((i < samples) && (hv_filtered_max < HV_Voltage_MAX_CHECK)) // check if less than HV_MIN to speed up test (basically stop testing if it has passed the check)
{
hv_adc_read[i] = check_adc(7);
if(hv_adc_read[i] > 0 && hv_adc_read[i] < 10)
{
hv_filtered_avg += hv_adc_read[i];
non_zero_samples++;
i++;
}
if((hv_adc_read[i] > hv_filtered_max) && hv_adc_read[i] < 10)
{
hv_filtered_max = hv_adc_read[i];
}
loops++;
if(loops > 500) // stop sampling at 500 if we never get anything (this is protection for it possibly freezing i we sample nothing)
{
hv_filtered_max = 0;
break;
}
}
hv_filtered_avg = hv_filtered_avg/non_zero_samples;
return std::make_tuple(hv_filtered_avg,hv_filtered_max);
}
hardware_control hwc;
//where I call and return the data
std::tie(Ins_Data.hv_avg,Ins_Data.hv_max) = hwc.hv_check();
//Me printing out the values
qDebug()<<"MAX_OUTSIDE"<<Ins_Data.hv_max<<endl;
Ins_Data.hv_errors = hwc.HV_error_check();
log_data.push_back("HV_AVG");
log_data.push_back(QString::number(Ins_Data.hv_avg*3));
log_data.push_back("HV_MAX");
log_data.push_back(QString::number(Ins_Data.hv_max*3));
Why this annoys me so bad is that every time I print it out with the qDebug() function it works! if I comment it out, it goes back to 3.8581*10^-38
The value magically comes back to the correct value.
What's going on here? My guess is the make_tuple and tie is corrupting the memory but if so then why is it only sporadically doing it? and why only one of the floats?
SOLVED
I was sampling beyond my initialized array. My array is set to "HV_SAMPLES" however the max number of loops was 500, therefore it sampled beyond the size of my array. Debug functionality must have added some cushion between the array and other values allowing it to output correctly.
As stated above my program works in Debug and Release without debug (ctrl + F5) however does not work in simply Release.
Just to clarify I have already checked to see if I have some uninitialized variables and I haven't (to the best of my knowledge anyway but I have spent quite some time looking).
I believe to have localized the issue and what I have come across is, in my opinion, very bizarre. First I set up the break points as shown in the picture below:
Then I run the program in release. And instantly the top break point moves:
I found this extremely odd. Now note the number 6302 assigned to 'n'. This number is correct and what I hoped to pass through. Now watch as I continue through the program.
We are still in good shape but then it turns for the worst.
'n' changes to 1178521344, which messes up the rest of my code.
Would someone be able to shed some light on the situation, and even better, offer a solution.
Thanks,
Kevin
Here is the rest of the function if it helps:
NofArr = n;
const int NA = n;
const int NAless = n-1;
double k_0 = (2*PI) / wavelength;
double *E = new double[NAless]; // array to hold the off-diagonal entries
double *D = new double[NA]; // array to hold the diagonal entries on input and eigenvalues on output
int sizeofeach = 0;
trisolver Eigen;
int* start; int* end;
vector< vector<complex <double>> > thebreakup = BreakUp(refidx, posandwidth, start, end);
for(int j = 0; j < (int)thebreakup.size(); j++){
// load the diagonal entries to D
for(int i =0; i < (int)thebreakup[j].size(); i++){
D[i] = -((double)2.0/(dx*dx)) + (k_0*k_0*thebreakup[j][i].real()*thebreakup[j][i].real());
}
// load the off diagonal
for(int i = 0; i < (int)thebreakup[j].size(); i++){
E[i] = (double)1.0 / (dx*dx);
}
sizeofeach = (int)thebreakup[j].size();
double *arr1= new double[sizeofeach];
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
complex <double> tmp( PhaseAndAmp[j][1]*cos(PhaseAndAmp[j][0]), PhaseAndAmp[j][1]*sin(PhaseAndAmp[j][0]));
// rebuild the break up with the mode
for(int i = 0; i < (int)thebreakup[j].size(); i++){
thebreakup[j][i] = (complex<double>(arr1[i],0.0)) * tmp ;
}
delete []arr1;
}
vector<complex<double>> sol = rebuild(thebreakup, start, end);
delete [] E;
delete [] D;
delete [] start;
delete [] end;
return sol;
I'm writing this as an answer, because it's way harder to write as a comment.
What strikes me immediately is the array "arr1"
First you allocate new memory and store a pointer to it in the variable arr1
double *arr1= new double[sizeofeach];
Then, immediately, you overwrite the address.
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
Later, you delete something. Is it safe?
delete []arr1;
It's not the double array you allocated, but something eigensolve returned. Are you sure you have the right to delete it? Try removing the delete here. Also, fix the memory leak too, by removing allocation in the first line I gave.
What worries me even more is that the "this" pointer changes. There is some nasty problem somewhere. At this point, your program has already been corrupted. Look for the issue somewhere else. Valgrind would be a GREAT tool if you can try to compile under linux.
It seems that there is some sort of code optimization going on in your program. It is not always easy to debug optimized code step-by-step since the optimization may reorder instructions.
I cannot see why the fact that 'n' changes to an apparently uninitialized value would be the root cause of the problem, since 'n' is anyways no longer used in your function. Seems like the memory is simply been released as part of the optimization.
I have discovered my mistake. Earlier in the program I was comparing pointers, not what they were pointing at. A stupid mistake but one I wouldn't have spotted without a long debugging session. My boss explained that the information given at the bottom of Visual Studio whilst in release mode cannot be trusted. So to "debug" I had to use std::cout and check variables that way.
So here is the mistake in the code:
if(start > end){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}
Where start and end were defined earlier as:
int* start = new int[NofStacks];
int* end = new int[NofStacks];
And initialized.
Thanks to all those who helped and I feel I must apologise for the stupid error.
The Fix being:
if(start[i] > end[i]){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}
I'm doing a group project at school, we're creating a 2d game, and I'm getting an exception I have no idea what to do with.
A side note: all of this is done in debug mode.
We have a physicsengine class that calculates collision and adds vector forces to entities, the code:
void PhysicsEngine::doPhysicsTick()
{
vector<vector<unordered_set<Entity*>>> *grid = this->grid.getGrid();
unordered_set<Entity*>* updatable = new unordered_set<Entity*>();
unordered_set<Entity*>* collidable = new unordered_set<Entity*>();
const int &r = CollisionGrid::C_GRID_RADIUS;
for (int row = 0; row < grid->size(); row++)
for (int col = 0; col < grid->at(row).size(); col++)
{
collidable->clear();
// put all surrounding grid blocks in a entity list to
// check against collision with the current block
int rw(row - r > 0 ? row - r : 0);
int cl(col - r > 0 ? col - r : 0);
for (int rrow = rw; rrow <= row + r && rrow < grid->size(); rrow++)
for (int rcol = cl; rcol <= col + r && rcol < grid->at(rrow).size(); rcol++)
for (Entity *e : grid->at(rrow).at(rcol)) // It crashes here
collidable->insert(e);
for (Entity *e : grid->at(row).at(col))
{
if (e->isFixed())
continue;
e->speed += gravity;
eBounds.reBox(e->location, e->getSize() + e->speed);
for (Entity *c : *collidable)
if (isOverlapping(eBounds, Box(c, c->getSize())) && e != c)
doCollision(e, c);
updatable->insert(e);
}
}
We have a separate collisiongrid class that manages the grid where we store our entities for collision check (so we don't have to check everything with everything)
the collisiongrid and its underlying vector are created when the constructor of the physicsengine is called PhysicsEngine::PhysicsEngine(World *world) : grid(world). But for some reason on only the first tick I see the vector grid points to something nonexistant (size being ridiculously large and such) inside of the loop that fills up collidable.
The error it throws is in the title. If I put a catch block around it, it'll just crash someplace else in some c++ library kind of randomly (different file every time)
and for some reason it crashes in our gameloop class' (the one calling tick of physicsengine) destructor if I don't comment the thing I put in there.
Gameloop::~Gameloop()
{
//if( t ) // t = #include <thread>
// delete t;
}
We are not allowed to use any libraries outside of the Win32 API and some default c++ libraries
Edit: I added some pictures (and undid the dynamic allocation of the unordered_sets)
what it should show:
what it sometimes shows on the first tick:
(notice how the pointers are the same, first two shot where made during the same run)
what it shows other times on the first tick:
Does your program handle tasks? Because this may solve your problem in that case (those kind of exceptions never crash the program at the right time!)
If not, then you need to debug the program some more. Like printing rrow, rrcol, grid->size(), grid->at(rrow)->size everytime before the line where it crashes.
But my money is on the concurrency / memory management side of the code. The fact that it crashes in the destructor in the delete part, makes me think maybe you are handling items that were already deleted elsewhere or concurrently handling items without the appropriate measures. And in your screenshot you have a bunch of size=??? which maybe means that your item/instance was deleted and your pointer points to free memory, causing the crash when accessing it in your loop. It's a tough error to solve.
Additionnally, you should be able to access parameters of your exception in the debugger, if you can, maybe you can post all of its contents?
I have a vector holding 10 items (all of the same class for simplicity call it 'a'). What I want to do is to check that 'A' isn't either a) hiding the walls or b) hiding another 'A'. I have a collisions function that does this.
The idea is simply to have this looping class go though and move 'A' to the next position, if that potion is causing a collision then it needs to give itself a new random position on the screen. Because the screen is small, there is a good chance that the element will be put onto of another one (or on top of the wall etc). The logic of the code works well in my head - but debugging the code the object just gets stuck in the loop, and stay in the same position. 'A' is supposed to move about the screen, but it stays still!
When I comment out the Do while loop, and move the 'MoveObject()' Function up the code works perfectly the 'A's are moving about the screen. It is just when I try and add the extra functionality to it is when it doesn't work.
void Board::Loop(void){
//Display the postion of that Element.
for (unsigned int i = 0; i <= 10; ++i){
do {
if (checkCollisions(i)==true){
moveObject(i);
}
else{
objects[i]->ResetPostion();
}
}
while (checkCollisions(i) == false);
objects[i]->SetPosition(objects[i]->getXDir(),objects[i]->getYDir());
}
}
The class below is the collision detection. This I will expand later.
bool Board::checkCollisions(int index){
char boundry = map[objects[index]->getXDir()][objects[index]->getYDir()];
//There has been no collisions - therefore don't change anything
if(boundry == SYMBOL_EMPTY){
return false;
}
else{
return true;
}
}
Any help would be much appreciated. I will buy you a virtual beer :-)
Thanks
Edit:
ResetPostion -> this will give the element A a random position on the screen
moveObject -> this will look at the direction of the object and adjust the x and Y cord's appropriately.
I guess you need: do { ...
... } while (checkCollisions(i));
Also, if you have 10 elements, then i = 0; i < 10; i++
And btw. don't write if (something == true), simply if (something) or if (!something)
for (unsigned int i = 0; i <= 10; ++i){
is wrong because that's a loop for eleven items, use
for (unsigned int i = 0; i < 10; ++i){
instead.
You don't define what 'doesn't work' means, so that's all the help I can give for now.
There seems to be a lot of confusion here over basic language structure and logic flow. Writing a few very simple test apps that exercise different language features will probably help you a lot. (So will a step-thru debugger, if you have one)
do/while() is a fairly advanced feature that some people spend whole careers never using, see: do...while vs while
I recommend getting a solid foundation with while and if/else before even using for. Your first look at do should be when you've just finished a while or for loop and realize you could save a mountain of duplicate initialization code if you just changed the order of execution a bit. (Personally I don't even use do for that any more, I just use an iterator with while(true)/break since it lets me pre and post code all within a single loop)
I think this simplifies what you're trying to accomplish:
void Board::Loop(void) {
//Display the postion of that Element.
for (unsigned int i = 0; i < 10; ++i) {
while(IsGoingToCollide(i)) //check is first, do while doesn't make sense
objects[i]->ResetPosition();
moveObject(i); //same as ->SetPosition(XDir, YDir)?
//either explain difference or remove one or the other
}
}
This function name seems ambiguous to me:
bool Board::checkCollisions(int index) {
I'd recommend changing it to:
// returns true if moving to next position (based on inertia) will
// cause overlap with any other object's or structure's current location
bool Board::IsGoingToCollide(int index) {
In contrast checkCollisions() could also mean:
// returns true if there is no overlap between this object's
// current location and any other object's or structure's current location
bool Board::DidntCollide(int index) {
Final note: Double check that ->ResetPosition() puts things inside the boundaries.