Occasional Pointer Failure

I’m making an Asteroids game and to handle collisions between objects, I’m storing them in a vector. I then loop through the vector of objects, check them for collisions, and call their update functions. This works fine...ish. My problem is that very occasionally, for no apparent reason, I get NaNs appearing in some of my variables. What I don’t understand is how they can work at some times and not others.

1
2
3
4
5
6
 for(std::vector<gameObject*>::iterator it=objects.begin(); it!=objects.end(); it++)//iterate through all the game objects
{
    ...
    vx1 = (*it)->getXV(); vy1 = (*it)->getYV();//these are the functions that sometimes fail
    ...
}


I believe the problem lies with the getXV and getYV functions (which are functions returning floats for horizontal and vertical velocity respectively) but I cannot for the life of me work out why it works for about 90% of the time.

Well, how do the functions look? Post some code.
float gameObject::getXV(){return xv;}

That’s it.
maybe your vector has some bad pointers?
How is xv updated?
@Disch How would I find out if it’s a bad pointer? It can run for minutes before running into problems.

@filipe xv is updated by a similar function: void gameObject::setXV(float v){xv = v;}
xv is updated by a similar function: void gameObject::setXV(float v){xv = v;}

Well, that still doesn't tell us anything about how that float is calculated. Who calculates the value of v and how?

BTW, how are you creating and deleting gameObjects? Inconsistent behavior is often caused by memory corruption.
And with what argument do you call setXV ?
xv is just a float, like 4.5 for example.

As for gameObjects, they are created and then a function called register adds them to the vector. This bit seems to work fine, I’ve used multiple cout statements all over the place to test things and I haven’t noticed anything unusual there.

Half of my problem is that I don’t know really what the error is. I’ve found that occasionally, xv will be NaN but I don’t know why. There doesn’t seem to be any pattern to the errors that I can see: a specific value or range doesn’t seem to produce the error each time which makes me believe it might be to do with the vector or pointers. Am I dereferencing the pointer correctly?
We can't really help you further if you don't post the relevant bits (whatever calculations are used to update the object's position based on its velocity (I'm assuming the velocity is fixed, as you said), object creation and object deletion, and insertion/removal from the vector).
Last edited on
I’m sorry, it’s quite a large chunk of code which would require a fairly in-depth explanation so I’m trying to keep it as light as possible. I guess that’s not helping xD

in the gameObject’s update function:
x+=xv;
y-=yv;

update is then called in the iteration:
(*it)->update();

The velocity is being updated based on 2D collisions. Here is the code for the collisions (it’s probably very inefficient but I’d like to get it to work first before I try anything else).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
void game::update(float f)
{
    for(std::vector<gameObject*>::iterator it=objects.begin(); it!=objects.end(); it++)
    {
        for(std::vector<gameObject*>::iterator itt=objects.begin(); itt!=objects.end(); itt++)
        {
            if(it!=itt) //make sure we don’t check an object against itself
            {
                double dx = 0, dy = 0, d = 0, dt = 0; //initialise some variables 
                
                dx = (*itt)->getX()-(*it)->getX(); //distance in x
                dy = (*itt)->getY()-(*it)->getY(); //distance in y
                d = sqrt(dx*dx + dy*dy); //pythagorean distance between the two objects
                
                if(d<((*it)->getRadius()+(*itt)->getRadius())) //if the distance is less than the sum of the bounding circles
                {
                    double ax = 0, ay = 0, vx1 = 0, vy1 = 0, vx2 = 0, vy2 = 0; //initialise more variables
                    
                    ax = dx/d; ay = dy/d; //get the normals 
                    
                    vx1 = (*it)->getXV(); vy1 = (*it)->getYV(); //get the velocities for object 1
                    vx2 = (*itt)->getXV(); vy2 = (*itt)->getYV(); //get the velocities for object 2
                    
                    double n1 = vx1*ax + vy1*ay; //more normalisation
                    double n2 = vx2*ax + vy2*ay;
                    
                    dt = (((*it)->getRadius()+(*itt)->getRadius()) - d)/(n1-n2); //how much the objects bounding circles overlap
                    
                    double x1 = (*it)->getX(), y1 = (*it)->getY(); //positions
                    double x2 = (*itt)->getX(), y2 = (*itt)->getY();
                    
                    (*it)->setX(x1-=(vx1*dt)); (*it)->setY(y1-=(vy1*dt)); //move the objects apart so that d = sum of bounding circles
                    (*itt)->setX(x2-=(vx2*dt)); (*itt)->setY(y2-=(vy2*dt));
                
                    double va1=(n1), vb1=(-n1); 
                    double va2=(n2), vb2=(-n2);
                
                    double vaP1=va1 + (1+ELASTICITY)*(va2-va1)/(1+((*it)->getSize()/((*itt)->getSize()))); //solve 1D collisions (I’m using a constant for size, which is returned by getSize()
                    double vaP2=va2 + (1+ELASTICITY)*(va1-va2)/(1+((*itt)->getSize()/((*it)->getSize())));
                    
                    vx1=vaP1*ax-vb1*ay;  vy1=vaP1*ay+vb1*ax; //the new velocities after the collision
                    vx2=vaP2*ax-vb2*ay;  vy2=vaP2*ay+vb2*ax;
                    
                    (*it)->setXV(vx1); (*it)->setYV(vy1); //set the velocities
                    (*itt)->setXV(vx2); (*itt)->setYV(vy1);
                    
                    x1 = (*it)->getX(); y1 = (*it)->getY(); //get the positions
                    x2 = (*itt)->getX(); y2 = (*itt)->getY();
                    
                    (*it)->setX(x1+=(vx1*dt)); (*it)->setY(y1+=(vy1*dt)); //adjust for the overlap given earlier
                    (*itt)->setX(x2+=(vx2*dt)); (*itt)->setY(y2+=(vy2*dt));
                }
            }
        }
        (*it)->update(f); //f is the framerate
        (*it)->wrapScreen(); //a function for making the objects wrap around the screen
    }
}
Topic archived. No new replies allowed.