2013-05-09 54 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