函数返回地址

问题描述

我是 CPP 的新手,我正在编写一个程序作为作业来模拟包含目的地并开始使用面向对象编程的火车路径系统。 我有 2 个类,如下所示(有一个乘客类,但不相关):


     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();
         }
    };

我有一个搜索功能,专门用于根据用户输入的命令查找起点和目的地,例如:用户输入“add_train cityname1 cityname2 ”。我的程序检测城市名称搜索一个向量,我用城市名称的键命名为车站,并返回一个指向该车站对象的指针(由于函数中内存行为的复杂性,我将其设置为指针)。 功能如下:

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;
    }} 

我的问题是我的搜索函数的奇怪行为,当我调试程序时,我看到该函数找到了正确的站对象并返回了一个指向它的指针,但是当执行返回到构造函数时,它随机地(可能不是随机地)将与起始站相关的第一个指针变为空,并用垃圾值替换里面的值。 但该函数搜索到目的站后没有这样做,执行是正确的。

有人能解释为什么会发生这个错误吗? 我的猜测是我对局部变量和指针返回的理解不够好,我在某处犯了一个菜鸟错误,但我似乎没有找到。

PS:我没有包含完整的代码,因为它太长了我可以通过附加文件来包含它,如果需要,请评论

解决方法

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

如果你仔细看这里,你会发现 stations 参数是按值传递的,这意味着这个函数返回后,这个stations 参数将被销毁。以后不会了。它将不复存在。它将成为一个前参数。

但是这个 station_search 返回一个指向这个向量中某个值的指针。因此,逻辑规则规定它将返回一个指向被销毁对象的指针。以任何方式尝试取消对该指针的引用都会变成未定义的行为。

您的其他类方法通过引用接收参数,因此您必须已经了解通过值传递参数与通过引用传递参数之间的区别,因此您应该在这里做同样的事情。

,

这里你传递了一个向量的副本,当函数返回时它会被销毁。此外,如果未找到键,则返回未初始化的指针。

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;
}

您应该传入一个引用并初始化dummy

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