2014-03-27 112 views
0

我有一個簡約TRAFIC模擬器:它是蜂窩式自動機至極在四個步驟的工作原理:段錯誤矢量構造

  • 加速度(1單元速度的)
  • 制動安全(-the數目的空單元格到下一個轎廂)
  • 隨機
  • 斷裂,以模擬驅動器的缺陷(-1或-O隨機地),
  • mooving(+轎廂細胞的速度)

我在mooving過程中遇到Segfault,在vector<vehicule*>的初始化過程中,它沒有得到向量的構造函數。 但是,當刪除破壞安全程序,我沒有任何段錯誤。人無我有,如果道路ILS的規模低於16

這裏是最少的代碼來獲得一個bug

#include <iostream> 
#include <vector> 

using namespace std; 

struct vehicule 
{ 
    vehicule(int v); 
    int vitesse;//speed 
    static int vMax; 
}; 
vehicule::vehicule(int v) 
{ vitesse=v; } 
int vehicule::vMax=5; 



void avancer(std::vector<vehicule*>&);//each car mooves their value of speed, of square on the road. 
void freinage_secu(std::vector<vehicule*>&);//each car slow down the number of cases betwen their and the next car. 
void add_veicule(std::vector<vehicule>&, std::vector<vehicule*>&); 

void afficher_route(std::vector<vehicule*>& road) 
{ 

    for (vehicule* v:road) 
    { 
     if (v==nullptr) 
     { cout<<"-"; } 
     else 
     { cout<<"x"; } 
    } 
    cout<<"\n"; 

} 




void freinage_secu(vector<vehicule*> &road) 
{ 
    int lng=road.size(); 
    int nbV=0; 
    int last; 
    int j=0; 

    for (unsigned int i=0;i<road.size();i++)//compter le nombres de vehicules 
    { 
     if(road[i]!=nullptr) 
     { 
      nbV++; 
     } 
    } 

    while(road[(j%lng)]==nullptr)//on se place sur le premier evicule 
    { j++; } 

    for (int i=0;i<nbV;i++) 
    { 
     last=j; 

     do 
     { 
      j++; 
     }while(road[j%lng]==nullptr); 

     if(road[last]->vitesse>(j+lng-last-1)%lng) 
     { 
      road[last]->vitesse=(j+lng-last-1)%lng; 
     } 
    } 
} 




void avancer(vector<vehicule*> &road) 
{ 
    vector<vehicule*> road2(road.size(),nullptr);//<<<--the bug comme there 

    for (unsigned int i=0;i<road.size();i++) 
    { 

     if (road[i]!=nullptr) 
     { 
      road2[(i+road[i]->vitesse)%road.size()]=road[i]; 
     } 
    } 

    road=road2; 

} 




void add_veicule(vector<vehicule> &V, std::vector<vehicule*>& road) 
{ 
    unsigned int i=0; 
    bool overload=1; 
    V.push_back(vehicule::vMax-vehicule::vMax/2); 

    while(road[i]!=nullptr&& i<road.size()) 
    { 
     i++; 
    } 

    if (i<road.size()) 
    { 
     road[i]=&V[V.size()-1]; 
     overload=0; 
    } 

    if (overload) 
    { 
     V.pop_back(); 
     cout<<"la route est saturée\n"; 
    } 

} 

/// --------------------------------main 
int main() 
{ 
    int nbV=16;//dont'bugs if it is lower than 16 (we can overload the road), bugs if <= 16 
    vector<vehicule> ensembleV; 
    vector<vehicule*> road(nbV,NULL);//the road is a ring. 
    string commande; 
    bool continuer=true; 
    add_veicule(ensembleV, road); 


    while(continuer) 
    { 
     freinage_secu(road);//slow down 
     avancer(road);//move foward 
     afficher_route(road); 
     cout<<"que voulez vous faire ?\n v\tincrémenter le nombre de vehicules\n quit\tquiter la simulation.\n"; 
     cin>>commande; 

     if(commande=="v") 
     { 
      add_veicule(ensembleV, road); 

     } 

     if(commande=="quit") 
     { 
      continuer=false; 
     } 


    } 

    return 0; 
} 

我把公路和ensembleV全球的空間,段錯誤仍那裏。

+0

「我在mooving過程中遇到Segfault,...」我的代碼中找不到mooving()。 – HAL

+0

這是'avancer'功能。 –

回答

1

此:

vector<vehicule*> road(nbV,NULL);//the road is a ring. 

應該是:

vector<vehicule*> road(nbV, nullptr);//the road is a ring. 

看來你的編譯器是騙你......在我的作品,沒有錯誤的休息,甚至有崩潰nbV = 1

+0

注意:矢量值 - 使用指定幅度的構造初始化其成員,並且每個標準的指針的值初始化爲'nullptr'。即'vector road(nbV);'就夠了。 – WhozCraig

+0

當然,儘管清楚地說明初始化值並沒有什麼壞處。我認爲這是一個品味問題。 – gg349

+0

沒錯,就像實際的算法一樣,我個人會爲'road.erase(std :: remove_if(road.begin(),road.end(),nullptr),road.end());'和稱它爲好。 – WhozCraig

0

IMO問題與此迴路有關:

while(road[i]!=nullptr && i<road.size()) 
{ 
    i++; 
} 

假設道路大小爲1,並且要素非空,則在第二次迭代時,您將首先檢查超出邊界的道路[1]。更改爲:

while(i<road.size() && road[i]!=nullptr) 

而且,你把你的道路矢量指針ensembleV元素:您可以通過調整即ensembleV

road[i]=&V[V.size()-1]; 

後。 push_back(可能會重新分配向量緩衝區),那些路上的指針不再有效,不確定這是否是問題的確切原因。

+0

它可能是一個bug的來源,但大多數情況下它可以運行(我改變它:'while(i luvf

+0

我不確定在使用只有在道路超載的情況下才使用pop_back()。我從不改變代碼中ensembleV的大小(在add_veicule()中除外)。我將bool超載的使用更改爲其他條件 – luvf