b3hn4m
b3hn4m

Reputation: 75

Initializing an object in a class constructor

There is a runtime error:

terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc Aborted (core dumped)

from the below c++ class:

class PoseDrawer
{
public:
  PoseDrawer() : tf_(),  target_frame_("turtle1"), tf_filter_(point_sub_, tf_, target_frame_, 10)
  {
    point_sub_.subscribe(n_, "turtle_point_stamped", 10);
    tf_filter_.registerCallback( &PoseDrawer::msgCallback, this );
  } ;


private:
  message_filters::Subscriber<geometry_msgs::PointStamped> point_sub_;
  tf::TransformListener tf_;
  tf::MessageFilter<geometry_msgs::PointStamped> tf_filter_;
  ros::NodeHandle n_;
  std::string target_frame_;

  void msgCallback(const boost::shared_ptr<const geometry_msgs::PointStamped>& point_ptr) 
  {
  //stuff
  }
};

It is due to the way the tf_filter_ is initialized because if I convert tf_filter_ to a pointer as below, it will work as expected. so what is the difference between the above and the below code?

class PoseDrawer
{
public:
  PoseDrawer() : tf_(),  target_frame_("turtle1")
  {
    point_sub_.subscribe(n_, "turtle_point_stamped", 10);
    tf_filter_=new tf::MessageFilter<geometry_msgs::PointStamped>(point_sub_, tf_, target_frame_, 10);
    tf_filter_->registerCallback( &PoseDrawer::msgCallback, this );
  } ;


private:
  message_filters::Subscriber<geometry_msgs::PointStamped> point_sub_;
  tf::TransformListener tf_;
  tf::MessageFilter<geometry_msgs::PointStamped>* tf_filter_;
  ros::NodeHandle n_;
  std::string target_frame_;

  void msgCallback(const boost::shared_ptr<const geometry_msgs::PointStamped>& point_ptr) 
  {
   //stuff
  };

};

Upvotes: 0

Views: 263

Answers (1)

danadam
danadam

Reputation: 3450

In the class you declare target_frame_ after tf_filter_ but you use it in tf_filter_ constructor. You should get warnings about that. Here's distilled example of what you are doing:

#include <string>

class PoseDrawer
{
public:
  PoseDrawer() : target_frame_("turtle1"), tf_filter_(target_frame_)
  {
  } 

private:
  std::string tf_filter_;
  std::string target_frame_;
};

See godbolt

<source>: In constructor 'PoseDrawer::PoseDrawer()':
<source>:12:15: warning: 'PoseDrawer::target_frame_' will be initialized after [-Wreorder]
   12 |   std::string target_frame_;
      |               ^~~~~~~~~~~~~
<source>:11:15: warning:   'std::string PoseDrawer::tf_filter_' [-Wreorder]
   11 |   std::string tf_filter_;
      |               ^~~~~~~~~~
<source>:6:3: warning:   when initialized here [-Wreorder]
    6 |   PoseDrawer() : target_frame_("turtle1"), tf_filter_(target_frame_)
      |   ^~~~~~~~~~

Move target_frame_ declaration before tf_filter_ and see if it helps.

Upvotes: 1

Related Questions