seg fault static class 用于动态分配的成员指针

seg fault static class member pointer used with dynamic allocation

我运行如图所示陷入段错误

cluster_init: /usr/include/boost/smart_ptr/shared_ptr.hpp:728: typename boost::detail::sp_dereference<T>::type boost::shared_ptr<T>::operator*() const [with T = pcl::PointCloud<pcl::PointXYZ>; typename boost::detail::sp_dereference<T>::type = pcl::PointCloud<pcl::PointXYZ>&]: Assertion `px != 0' failed.
Aborted (core dumped)

我指出了我的问题,我怀疑这与我使用静态 class 有关,它纯粹只有静态成员和静态函数。我很确定问题出在成员 mCoefficients 上,因为在我实现该部分之前代码正在运行。
我将如何初始化静态成员 mCoefficients 以便我不会 运行 进入这个段错误?我尝试在 cpp 文件中初始化它,同时在头文件中声明它,但它似乎不起作用。

#ifndef POINTCLOUDPROCESSOR_H
#define POINTCLOUDPROCESSOR_H

// Include the ROS library
#include <ros/ros.h>
#include <pcl_ros/point_cloud.h> 

// Include pcl
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/crop_box.h>
#include <pcl/filters/project_inliers.h>
#include <pcl/ModelCoefficients.h>

namespace ocb
{
typedef pcl::PointCloud<pcl::PointXYZ>::Ptr type_pclcloudptr;
class PointCloudProcessor
{
  public:

  static type_pclcloudptr ROS_to_PCL(sensor_msgs::PointCloud2Ptr& ros_msg);
  static type_pclcloudptr transform_frame(type_pclcloudptr& sourcecloud,Eigen::Affine3f& transform); 
  static type_pclcloudptr merge_pointclouds(type_pclcloudptr& msg1, type_pclcloudptr& msg2, type_pclcloudptr& msg3, type_pclcloudptr& msg4);

  static type_pclcloudptr groundbus_removal(type_pclcloudptr& input);
  static void init_passfilter();
  static void init_plane_transform();
  static type_pclcloudptr planar_transformation(type_pclcloudptr& input);

  private:

  static pcl::PassThrough<pcl::PointXYZ> mGroundAirfilter;
  static pcl::CropBox<pcl::PointXYZ> mBusfilter;
  static pcl::ModelCoefficients::Ptr mCoefficients;
  static pcl::ProjectInliers<pcl::PointXYZ> mProj;

};
} //namespace close scope

#endif //for POINTCLOUDPROCESSOR_H
#include <PointCloudProcessor.h>
#include <pcl/common/transforms.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/common/io.h>

namespace ocb
{
  pcl::PassThrough<pcl::PointXYZ> PointCloudProcessor::mGroundAirfilter;
  pcl::CropBox<pcl::PointXYZ> PointCloudProcessor::mBusfilter;
  pcl::ModelCoefficients::Ptr PointCloudProcessor::mCoefficients(new pcl::ModelCoefficients);
  pcl::ProjectInliers<pcl::PointXYZ> PointCloudProcessor::mProj;
  type_pclcloudptr PointCloudProcessor::ROS_to_PCL(sensor_msgs::PointCloud2Ptr& ros_msg)
  { 
    type_pclcloudptr pcl_msg(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromROSMsg(*ros_msg, *pcl_msg);
    return pcl_msg;
  }
  type_pclcloudptr PointCloudProcessor::transform_frame(type_pclcloudptr& sourcecloud,Eigen::Affine3f& transform)
  {
    type_pclcloudptr destcloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::transformPointCloud(*sourcecloud, *destcloud,transform);
    return destcloud;
  }
  type_pclcloudptr PointCloudProcessor::merge_pointclouds(type_pclcloudptr& msg1, type_pclcloudptr& msg2, type_pclcloudptr& msg3, type_pclcloudptr& msg4)
  {
    type_pclcloudptr mergedcloud(new pcl::PointCloud<pcl::PointXYZ>); 
    
    mergedcloud = msg1;
    *mergedcloud += *msg2;
    *mergedcloud += *msg3;
    *mergedcloud += *msg4;
    return mergedcloud;
  }
  type_pclcloudptr PointCloudProcessor::groundbus_removal(type_pclcloudptr& input)
  {
    type_pclcloudptr filtered_cloud1(new pcl::PointCloud<pcl::PointXYZ>);
    type_pclcloudptr filtered_cloud2(new pcl::PointCloud<pcl::PointXYZ>);
    PointCloudProcessor::mGroundAirfilter.setInputCloud(input);
    PointCloudProcessor::mGroundAirfilter.filter(*filtered_cloud1);
    PointCloudProcessor::mBusfilter.setInputCloud(filtered_cloud1);
    PointCloudProcessor::mBusfilter.filter(*filtered_cloud2);
    return filtered_cloud2;
  }
  void PointCloudProcessor::init_passfilter()
  {
    PointCloudProcessor::mGroundAirfilter.setFilterFieldName("z");
    PointCloudProcessor::mGroundAirfilter.setFilterLimits(0.5 , 4.2);
    PointCloudProcessor::mGroundAirfilter.setFilterLimitsNegative (false);
    PointCloudProcessor::mBusfilter.setMin(Eigen::Vector4f(-2.0, -1.75, 0.0, 1.0));
    PointCloudProcessor::mBusfilter.setMax(Eigen::Vector4f(5.9, 1.75, 3.5, 1.0));
    PointCloudProcessor::mBusfilter.setNegative(true);
  }
  void PointCloudProcessor::init_plane_transform()
  {
    PointCloudProcessor::mCoefficients->values.resize(4);
    PointCloudProcessor::mCoefficients->values[0] = 0.0;
    PointCloudProcessor::mCoefficients->values[1] = 0.0;
    PointCloudProcessor::mCoefficients->values[2] = 1.0;
    PointCloudProcessor::mCoefficients->values[3] = 0.0;
    PointCloudProcessor::mProj.setModelCoefficients(PointCloudProcessor::mCoefficients);
    PointCloudProcessor::mProj.setModelType(pcl::SACMODEL_PLANE);
  }
  type_pclcloudptr PointCloudProcessor::planar_transformation(type_pclcloudptr& input)
  {
    type_pclcloudptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);
    PointCloudProcessor::mProj.setInputCloud(input);
    PointCloudProcessor::mProj.filter(*filtered_cloud);
    return filtered_cloud;
  }

}

您可能患有 Static Initialization Order Fiasco

一种可能的补救方法是通过将静态变量隐藏在具有 static 变量的函数中来延迟初始化静态变量。它将在第一次使用时被实例化。

示例:

static pcl::ModelCoefficients::Ptr& mCoefficients(); // now a function

实施:

pcl::ModelCoefficients::Ptr& PointCloudProcessor::mCoefficients() {
    static pcl::ModelCoefficients::Ptr instance(new pcl::ModelCoefficients);
    return instance;
}

用法:

void PointCloudProcessor::init_plane_transform() {
    PointCloudProcessor::mCoefficients()->values.resize(4);
    PointCloudProcessor::mCoefficients()->values[0] = 0.0;
    PointCloudProcessor::mCoefficients()->values[1] = 0.0;
    PointCloudProcessor::mCoefficients()->values[2] = 1.0;
    PointCloudProcessor::mCoefficients()->values[3] = 0.0;
    PointCloudProcessor::mProj.setModelCoefficients(PointCloudProcessor::mCoefficients());
    PointCloudProcessor::mProj.setModelType(pcl::SACMODEL_PLANE);
}

对其他 static 变量也做同样的事情。

免责声明:我不知道您使用的框架,也无法对此进行测试。