Pearman
Pearman

Reputation: 1068

Segfault when accessing non-null pointer?

The code works fine in a Linux environment, but in Windows it crashes 5-10 seconds after the program starts. The debugger points to n->fired = true; as the problem?

void ParticleSystem::PrivProcessParticles(pNodePtr n, double frameTime)
{
      while(n != NULL) {
        n->fired = true;
        if(!n->immortal)
            n->life -= frameTime; //Decrement life
        n->particle.ApplyAccel2D(frameTime);

        /* Since the oldest particles will always be on
           top of the queue, if life is zero, dequeue! */
        if(n->life <= 0) {
            if(head != NULL && !n->immortal) {
                pNodePtr curr;
                curr = head;
                head = head->next;
                delete curr;
            }
        }
        n = n->next;
    }
}

Allocation:

void ParticleSystem::AddParticle(double lifeIn, double x, double y, double angle,
                                 double size, double force, bool immortalIn)
{
    //Increment particle count
    count++;

    //Allocate
    pNodePtr n = new particleNode;

    //Initialize
    n->particle.CreateQuad(size);
    n->particle.SetTexture(texture);
    n->particle.SetPos2D(x, y);
    n->particle.SetRot2D(angle);
    n->particle.SetTopSpeed(topSpeed);
    n->particle.SetVelocity(force);

    n->life = lifeIn;
    n->immortal=immortalIn;
    n->fired = false;
    n->next = NULL;

    //Place
    if (head == NULL) 
    {
        head = n;
        tail = n;
        n->next = NULL;
    } else {
        tail->next = n;
        tail = n;
    }
}

Node:

struct particleNode {
        Quad particle;
        double life;
        bool fired;
        bool immortal;
        particleNode* next;
};

Upvotes: 1

Views: 1786

Answers (1)

AnT stands with Russia
AnT stands with Russia

Reputation: 320451

There's not enough information posted. However, here's one potential source of the problem.

When your PrivProcessParticles function performs its iterations over n, it can decide to delete head element of your list. But is it possible that at the moment when it decides to delete head, n is actually the same as head? If so, deleting head turns n into a dangling pointer, which leads to disastrous consequences at n = n->next.

Add assert(curr != n) before delete curr and see whether that assertion holds or fails.

Anyway, what is the starting value of n passed to PrivProcessParticles by the caller? Can it by any chance happen to be the same as head?

P.S. Also, just out of curiosity, the logic that you use to decide whether to perform the deletion or not seems to suggest that the decision is actually made about node n (you check n->life <= 0 and n->immortal). But then you proceed to delete head, not n... Is that by design?

P.P.S. A nitpick: you are doing excessive n->next = NULL initializations in your AddParticle.

Upvotes: 1

Related Questions