2013-05-09 97 views
0

该代码在Linux环境下工作正常,但在Windows中,程序启动后它会崩溃5-10秒。调试器指向n->fired = true;作为问题?访问非空指针时发生Segfault?

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; 
    } 
} 

分配:

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; 
    } 
} 

节点:

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

仅仅因为它不为空,并不意味着它指向一个有效的对象。 – 2013-05-09 20:38:42

+0

如何验证对象是否是问题? – Graztok 2013-05-09 20:46:39

+0

看看指针,看它是否像0xDEADBABE之类的东西。您要么使用单位化,要么使用悬空指针释放,要么可能损坏指针的内存。 – 2013-05-09 20:46:43

回答

0

有没有贴的足够信息。但是,这是问题的一个潜在来源。

当您的PrivProcessParticles函数执行迭代超过n时,它可以决定删除列表中的head元素。但是有可能在决定删除head时,n实际上与head相同吗?如果是这样,删除headn变成一个悬挂指针,从而在n = n->next处导致灾难性后果。

delete curr之前加上assert(curr != n),看看这个断言是否成立。

无论如何,调用者将n的起始值传递给PrivProcessParticles是什么?它可能碰巧和head一样吗?

P.S.此外,出于好奇,您用来决定是否执行删除的逻辑似乎表明,该决定实际上是关于节点n(您检查n->life <= 0n->immortal)。但是,然后你继续删除head,而不是n ...是由设计?

P.P.S.挑剔:你在AddParticle中做了过多的n->next = NULL初始化。

+0

添加断言导致它失败。头正在传递给函数。 – Graztok 2013-05-09 20:57:06

+0

最早的粒子,将在列表的开始,将是第一个死亡。因此,我删除头并将头指针前移到队列中的下一个节点。 – Graztok 2013-05-09 21:10:22

+0

@Graztok:那么,如果断言失败了,那么这就是你的问题。您正在删除'n'下的数据,然后尝试在'n = n-> next'处读取死区。 – AnT 2013-05-09 21:16:51