0

I am new to CPP and I am writing a program as an assignment to simulate a train path system that includes destinations and starts using object oriented programming . I have 2 classes as shown below (there is a a passenger class but it is not relevant ) :


     class Train
    {
    public:
         int cooldown_time;
         int travel_time;
         int time_since_movement;
         int id;
         class Station *start;
         class Station *destination;
         vector<Passenger *> current_passengers;
         string status;
         void add_train(vector<string> commands, vector<Station> stations, vector<Train> &trains)
         {
              travel_time = stoi(commands[THIRD_PART + 1]);
              cooldown_time = stoi(commands[THIRD_PART + 2]);
              status = TSTATUS1;
              start = station_search(stations, commands[SECOND_PART]); // this is where the problem happens
              destination = station_search(stations, commands[THIRD_PART]);
              id = stations.size();
         }
    };
    class Station
    {
    public:
         int tuffy_price;
         string city_name;
         vector<Passenger *> current_passengers;
         vector<Train *> current_trains;
         int id;
         void add_station(vector<Station> &stations, vector<string> &commands)
         {
              tuffy_price = stoi(commands[THIRD_PART]);
              city_name = commands[SECOND_PART];
              id = stations.size();
         }
    };

I have a search function dedicated to finding the start and destination based off a command that user enters for example :the user enters "add_train cityname1 cityname2 <cooldown_time> <travel_time>". my program detects the city names and searches a vector I have named stations with a key that is the city name and returns a pointer (because of the complications in memory behavior in a function , i set it to pointer) to that station-object . the function is as below :

Station *station_search(vector<Station> stations, string key)
    {
         Station *dummy;
         for (int i = 0; i < stations.size(); i++)
         {
              if (stations[i].city_name == key)
              {
                   return &stations[i];
              }
         }
         return dummy;
    }} 

my problem is with my search function's weird behavior , when I debug the program I see the function find the correct station object and return a pointer to it ,but when the execution returns to the constructor function it randomly (maybe not randomly ) turns the first pointer relating to the start station to null and replaces the values inside with garbage ones. but after the function searches for the destination station it does not do this and the execution is correct.

Could someone explain why this error is occurring? My guess is that I have not understood local variables and pointer returns well enough and I have committed a rookie mistake somewhere but I don't seem to find it .

PS: I did not include the full code as it's too long I can include it by attaching a file ,comment down if it's necessary.

2 Answers2

1
Station *station_search(vector<Station> stations, string key)

If you take a closer look here, you will see that the stations parameter is passed by value, which means that after this function returns, this stations parameters will get destroyed. It will be no more. It will cease to exist. It will become an ex-parameter.

However this station_search returns a pointer to some value in this vector. Therefore, rules of logic dictate that it will return a pointer to a destroyed object. Attempting to dereference that pointer, in any way, becomes undefined behavior.

Your other class methods receive parameters by reference, so you must already understand the difference between passing parameters by value vs. by reference, so you should simply do the same here.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • I believe this is the solution , I do actually understand the pass by reference/ value concept , however I failed to note that I made this mistake ,can you also mention why the function returns the second pointer correctly but only fails for the first one ? – Pouriyatajmehrabi Apr 20 '21 at 12:20
  • Same reason why you will win the lottery if you play it several hundred million times. [Undefined behavior means anything can happen](https://stackoverflow.com/questions/32132574/does-undefined-behavior-really-permit-anything-to-happen), which might mean the expected result, every once in a blue moon. – Sam Varshavchik Apr 20 '21 at 12:22
1

Here you are passing a copy of the vector, which is destroyed when the function returns. Additionally, if the key is not found an uninitialized pointer is returned.

Station *station_search(vector<Station> stations, string key)
{
     for (Station &station :  stations)
     {
          if (stations.city_name == key)
          {
               // Pointer becomes invalid when you leave.
               // Accessing this pointer will cause undefined behavior.
               return &station;
          }
     }
     // This would always cause undefined behavior as dummy was not initialized.
     return nullptr;
}

You should pass in a reference and initialize dummy:

Station *station_search(vector<Station> &stations, string key)
Devolus
  • 21,661
  • 13
  • 66
  • 113