Reputation: 11
I have a minimalist trafic Simulator: it is cellular automaton wich works in four steps :
I get a Segfault in the mooving procedure, during the initalisation of a vector<vehicule*>
it don't get in the constructor of the vector.
But when remove the breaking saftety procedure I don't have any segfault. I have no one if the the size of the road ils lower than 16.
here is the minimal code to get a 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;
}
I put the road and ensembleV to global space, the segfault is still there.
Upvotes: 0
Views: 493
Reputation: 50046
IMO problem is with this loop:
while(road[i]!=nullptr && i<road.size())
{
i++;
}
suppose road is of size 1, and elements are non null, then on second iteration you will first check road[1] which is outside bounds. Change this to :
while(i<road.size() && road[i]!=nullptr)
Also, you put in your road vector pointers to ensembleV elements:
road[i]=&V[V.size()-1];
after you resize ensembleV by ie. push_back (which might reallocate vector buffer), those pointers in road are no longer valid, not sure if this is the exact cause of your problem.
Upvotes: 0
Reputation: 35458
This:
vector<vehicule*> road(nbV,NULL);//the road is a ring.
should be:
vector<vehicule*> road(nbV, nullptr);//the road is a ring.
Seems your compiler is tricking you ... in the rest it works for me, no errors, or crashes even with nbV = 1
Upvotes: 1