简体   繁体   中英

seg fault static class member pointer used with dynamic allocation

I am running into seg fault as shown

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)

I pinpoint my problem and i suspect it has something to do with my use of a static class which has purely only static members and static functions. I am pretty sure the problem arises from the member mCoefficients as the code was working before i implemented that part.
How would i initialise the static member mCoefficients so that i do not run into this seg fault? I have tried initialising it in the cpp file while having its declaration in the header file but it does not seem to be working.

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

}

You could be suffering from Static Initialization Order Fiasco .

One possible remedy is to do lazy initialization of your static variables by hiding them in functions with a static variable. It'll then be instantiated upon first use.

Example:

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

Implementation:

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

Usage:

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

Do the same with the other static variables too.

Disclaimer: I don't know the framework you use and have no way of testing this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM