【问题标题】:Vector of Object and pointer in Class Object - Core Dump (segmentation fault)类对象中的对象向量和指针 - 核心转储(分段错误)
【发布时间】:2021-06-02 23:20:09
【问题描述】:

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

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

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

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

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

这是我的完整代码:

  class DroneTopic
    {
      protected:
        struct Waypoint{
          int x,y,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,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-loop”,但由于某种原因我不明白它没有出来并给我这个错误:

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


【问题讨论】:

  • "crash" 之前在该行停止时,您在调试器中观察到了什么?当时kj的值是多少?恐怕您正在尝试使用一些已经悬而未决的东西,但是如果没有看到minimal reproducible example(强调minimal),这很难说。
  • 在您的read_logs 函数中,delete ptr 感觉不对。除了您只删除分配给ptrlast 赋值之外,指针指向的对象还不是您自己用new 创建的。
  • 你甚至不需要 ptr。为什么不使用例如tmp.x = logs[i]["x"].asInt()?
  • 嗨,@Someprogrammerdude 我不能直接使用你建议的 Json::Value 类型不仅仅是一个“int”,而是一个“const signed int”或类似的东西。错误会告诉我它不能将 const signed int 放入 int var。
  • intsigned int 相同。而且你总是可以复制一个常量值(到一个非常量变量,这就是从函数返回常量值没有意义的原因)。

标签: c++ c++11 pointers stdvector


【解决方案1】:

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

read_logs() 函数被设置为 std::vector&lt;Waypoint&gt; 函数,但我从不使用 return 语句,因为我不需要将向量放在对象之外。

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

感谢您的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-04
    • 2015-05-12
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 2023-03-09
    • 2023-04-04
    • 2016-09-07
    相关资源
    最近更新 更多