KostasKol
KostasKol

Reputation: 111

Segmentation fault (core dumped) - Access violation reading location x

I'm writing a somewhat toy program to get into c++. However I'm having quite a lot of trouble with a segmentation fault at a very specific line in my code. I know that the segmentation fault means I tried to access memort that was not given to my program. The code is (somewhat) as follows(it's actually too big to just copy paste) :

class car {
protected:
   int speed;
   std::string brand;
public:
   car (int s, std::string b):speed(s),brand(b) {
       std::cout << "New car has been created" << endl;
   }
   virtual int is_stopped () {
      if (speed==0) return 1;
      else return 0;
   }
   virtual void speed_up () {
       speed++;
   }
   car* clone () {
      car* tmp(this);
      return tmp;
   }
};
class fast_car : public car {
public:
   fast_car (int s, std::string b):car(s,b) { } 
};
class slow_car : public car {
public:
   slow_car (int s, std::string b):car(s,b) { }
};
class highway {
   int number_of_cars;
   car **first;           //There are derived classes from car hence the                double pointer
public:
   highway (int c, int s, std::string b):number_of_cars(c) {
      first = new car*[c];
      for (int i=0;i<c/2;i++)
          first[i] = new fast_car (s,b);
      for (int i=c/2;i<c;i++)
          first[i] = new slow_car (s,b);
   }
   void speed_up () {
      int pos;
      pos = rand()%number_of_cars;    //give me a random number between 0 and number_of_cars;
      if (pos!=0) pos--;   //We don't want position -1
          first[pos]->speed_up ();
      clone_fast (first[pos], (number_of_cars - pos - 1)); //the second argument is the remaining array "spots" until the end of the array
   }



   void clone_fast (car* cur, int rem) {
      car* tmp;
      for (int i=-;i<=rem;i++) 
         if ((cur+1)->is_stopped ()) {   //Exact line where I get the segmentation fault
            tmp = cur->clone ();
            cur++;
         }
   }
};

So there it is. I tried to give you everything I could to recreate the problem. I'll try to solve any further questions. Any help would be greatly appreciated.

Upvotes: 0

Views: 288

Answers (2)

kebs
kebs

Reputation: 6697

I would suggest removing all pointer crap, and use more modern idioms. You can expand on the code below. However, it is unclear to me why you have two derived classes: they have no specific data neither methods, so why ?

class car
{
private:
    int speed;
    std::string brand;

public:
    car (int s, std::string b):speed(s),brand(b)
    {
        std::cout << "New car has been created" << endl;
    }
    bool is_stopped ()
    {
        return speed==0;
    }
    void speed_up ()
    {
        speed++;
    }
};

class fast_car : public car
{
    public:
        fast_car (int s, std::string b):car(s,b) {}
};

class slow_car : public car
{
    public:
        slow_car (int s, std::string b):car(s,b) {}
};

class highway
{
    private:
        std::vector<std::shared_ptr<car>> v_cars;
    public:
        highway (int c, int s, std::string b):number_of_cars(c)
        {
            for (int i=0;i<c/2;i++)
                v_cars.push_back( std::make_shared<fast_car>(s,b) );
            for (int i=c/2;i<c;i++)
                v_cars.push_back( std::make_shared<slow_car>(s,b) );
        }

};

int main()
{
    highway h( 50, 20 );
    return 0;
}

Upvotes: 0

user2475059
user2475059

Reputation: 133

The car*s are created by new, and aren't necessarily contiguous; they certainly aren't arrays that you can pointer-arithmetic around with. (car*) + 1 is not the same as (car**)[i + 1] (which is more like (car**) + 1). You probably want something a bit more like (*(first + 1))->doThing(), not (first[X] + 1)->doThing().

Edit: to be a bit more clear, if you can't do car[X + 1], then you can't do *(car + 1). Since the cars in clone_fast() are object pointers and not arrays, you can't do car[X + 1], thus (cur + 1)->is_stopped() is wrong.

Upvotes: 1

Related Questions