类对象中的对象向量和指针 - 核心转储分段错误

问题描述

我正在尝试在 c++11 中创建一个 ROS 节点,该节点将获取存储在 json 文件中的坐标以将它们发布到特定的 rostopic 上(附上 json 文件供您查看结构)。

我决定创建一个名为“Dronetopic”的类对象,它将从 json 文件中读取日志,创建一个发布者对象,然后在其中发布。

我面临的主要问题是指针的使用。由于我使用的库中的 Json 类型 (jsoncpp) 是特殊类型(例如 const 签名的 int),我必须使用指针来获取值并将其作为 int 传输到正确的属性

我还使用此类对象的向量来更轻松地处理对象数量,因为一开始我不知道我将要处理多少个 rostopic。

关于航点数量的类对象内部也发生了同样的情况。我所有的无人机对象不会有相同数量的航点,这就是为什么我创建了一个结构向量 (x,y,z) 来处理不断变化的数字。

这是我的完整代码

  class Dronetopic
    {
      protected:
        struct Waypoint{
          int x,z;
        };
        std::string topicName;
        ros::Publisher pub;
        std::vector<Waypoint> waypoints;
    
      public:
        Dronetopic(std::string topic,ros::NodeHandle &nh)
        {
          topicName = topic;
          pub = nh.advertise<geometry_msgs::Pose>(topicName,1000);
        }
        //Methodes
        std::vector<Waypoint> read_logs(Json::Value &logs){
          int nb_waypts = logs.size();
          Json::Value *ptr;
          Waypoint tmp {0,0};
    
          for(int i=0; i < nb_waypts; i++){
            ptr = &logs[i]["x"];
            tmp.x = ptr->asInt();
            ptr = &logs[i]["y"];
            tmp.y = ptr->asInt();
            ptr = &logs[i]["z"];
            tmp.z = ptr->asInt();
            waypoints.push_back(tmp);
            std::cout << i << std::endl;
          }
          delete ptr;
          ptr=NULL;
        }
    
        void publish_message()
        {
          for(int i = 0; i<waypoints.size();i++){
            geometry_msgs::Pose msg;
            msg.position.x=waypoints[i].x;
            msg.position.y=waypoints[i].y;
            msg.position.z=waypoints[i].z;
            pub.publish(msg);
          }
        }
    
    };
    
    
    std::string filename;
    
    int main(int argc,char **argv)
    {
      //Init ROS Node
      ros::init(argc,argv,"mesa2drone");
      ros::NodeHandle nh;
      ROS_INFO_STREAM("MESA Node Up");
      nh.param<std::string>("Json_File_Name",filename,"output");
      std::string extension = ".json";
      filename+=extension;
    
      Json::Value logs;
      std::ifstream jfile(filename);
    
      jfile >> logs;
    
      // Create vector of Dronetopic
      std::vector<Dronetopic> drone;
    
      drone.push_back(Dronetopic("test",nh));
      int nb_drone = logs.size();
    
      if(nb_drone > 0){
        for(int i=1;i<=nb_drone;i++){
          std::string j = std::to_string(i);
          std::ostringstream flux;
          flux << "intelaero_laserscan_" << j <<"/new_target";
          std::string name =  flux.str();
          std::cout<< "ok_3" <<std::endl;
          drone.push_back(Dronetopic(name,nh));
          std::cout<< "ok_5" <<std::endl;
        }
      }
    
      ros::Rate rate(1);
      while(ros::ok())
      {
        for(int k=1; k<=nb_drone;k++)
        {
          std::cout<<"ok_6"<<std::endl;
          std::string j = std::to_string(k);
          drone[k].read_logs(logs[j]);
          std::cout<<"ok_7"<<std::endl;
          drone[k].publish_message();
          std::cout<<"ok_8"<<std::endl;
        }
    
        //j++;
        rate.sleep();
      }
    
      ros::shutdown();
    
      return 0;
    }

我使用(但为了清楚起见删除了)std::cout 标记来查看代码崩溃的位置,并且似乎在这一行崩溃了:

drone[k].read_logs(logs[j]);

它实际上从未脱离函数。它执行完整的“for 循环”,但由于某种原因我不明白它没有退出并给我这个错误

Erreur de segmentation (core dumped)

据我所知,这与错误的分配有关,但我检查了向量的大小,一切正常(或者我认为是这样)。

如果我为此苦苦挣扎了几天,任何帮助将不胜感激。

谢谢!

FIY:我使用的是 Linux Ubuntu 16、c++11(不是我的选择)。

PS:这是我正在使用的 json 文件

{
 "1": [
  {
   "x": -2,"y": 27.5,"z": 20.0
  },{
   "x": -2,"y": 67.5,"z": 12.0
  },"y": 91.5,"z": 11.5
  },"y": 89.5,"z": 9.5
  },"y": 23.0,"z": 17.0
  },"y": 50.5,"z": 1.5
  },"y": 82.5,"z": 5.5
  },"y": 97.5,"z": 21.0
  }
 ],"2": [
  {
   "x": -2,"y": 64.0,"z": 0.0
  },"y": 160.5,"z": 11.0
  },"y": 85.5,"z": 14.0
  },"y": 132.0,"z": 19.0
  },"y": 146.0,"z": 1.0
  }
 ],"3": [
  {
   "x": -2,"y": 137.5,"y": 156.5,"z": 17.5
  },"y": 28.0,"z": 4.0
  },"y": 67.0,"z": 15.0
  },"y": 40.0,"y": 81.0,"z": 5.0
  },"y": 77.0,"z": 0.0
  }
 ]
}


解决方法

好的,我终于找到了主要问题。

read_logs() 函数被设置为 std::vector<Waypoint> 函数,但我从未放置 return 语句,因为我不需要在对象之外获取向量。

这就是导致错误的原因。我用 void read_logs() 替换了它,它现在可以工作了! 多么愚蠢的错误^^

感谢您的帮助。