luvf
luvf

Reputation: 11

segfault in vector constructor

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

Answers (2)

marcinj
marcinj

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

Ferenc Deak
Ferenc Deak

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

Related Questions