1

我有以下回调函数,旨在订阅 ROS 图像,将图像转换为 openCV IplImage* 以进行 blob 跟踪,然后释放内存。

void ImageCb(const sensor_msgs::ImageConstPtr &msg)
{
   cv_bridge::CvImagePtr cv_ptr;
   try {
   cv_ptr = cv_bridge::toCvCopy(msg, enc::BGR8);
   }
   catch (cv_bridge::Exception& e){
      ROS_ERROR("cv_bridge exception: %s", e.what());
      return;
   }

   IplImage *imageBGR, *imageRaw;

   imageRaw = cvCreateImage( cvSize(640,480) ,IPL_DEPTH_8U,3);
   imageBGR = cvCreateImage( cvSize(640,480) ,IPL_DEPTH_8U,3);

   *imageRaw = cv_ptr->image.operator IplImage();
   imageBGR = cvCloneImage( imageRaw );

   //do stuff...

   cvReleaseImage( &imageBGR ); 
   cvReleaseImage( &imageRaw ); //<-- seg fault if included
}

如果我包含 cvReleaseImage( &imageRaw ) 和内存泄漏(在短时间内导致 std::bad_alloc() ),则从函数返回时会出现分段错误。我通过 valgrind 运行可执行文件并确认在回调范围之后发生分段错误。看起来,在函数内部,我释放了 921,624 字节的图像数据。在函数 boost 之后,ROS 和 OpenCV 进程分别将内存 0、12 和 921,616 字节释放到已释放的内存块中。valgrind 的输出发布在下面 - 有什么想法吗?

==32750== Invalid read of size 4
==32750==    at 0x4229CD6: boost::detail::sp_counted_impl_pd<cv_bridge::CvImage*, boost::detail::sp_ms_deleter<cv_bridge::CvImage> >::dispose() (mat.hpp:366)
==32750==    by 0x80779AF: boost::detail::shared_count::~shared_count() (shared_count.hpp:217)
==32750==    by 0x8078991: boost::shared_ptr<cv_bridge::CvImage>::~shared_ptr() (shared_ptr.hpp:168)
==32750==    by 0x8073F2C: ImageCb(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (state_sensor.cpp:185)
==32750==    by 0x807DE6A: boost::detail::function::void_function_invoker1<void (*)(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&), void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (function_template.hpp:112)
==32750==    by 0x4759603: image_transport::RawSubscriber::internalCallback(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&) (function_template.hpp:1013)
==32750==    by 0x4756802: boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void, boost::_mfi::mf2<void, image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&>, boost::_bi::list3<boost::_bi::value<image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >*>, boost::arg<1>, boost::_bi::value<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> > > >, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (mem_fn_template.hpp:280)
==32750==    by 0x474C965: boost::detail::function::void_function_obj_invoker1<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)>, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> >::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const>) (function_template.hpp:1013)
==32750==    by 0x475FBFE: ros::SubscriptionCallbackHelperT<boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, void>::call(ros::SubscriptionCallbackHelperCallParams&) (function_template.hpp:1013)
==32750==    by 0x4128C06: ros::SubscriptionQueue::call() (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40D8A86: ros::CallbackQueue::callOneCB(ros::CallbackQueue::TLS*) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40DA563: ros::CallbackQueue::callAvailable(ros::WallDuration) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==  Address 0x1c9ae320 is 921,616 bytes inside a block of size 921,624 free'd
==32750==    at 0x402C06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32750==    by 0x43EE3D1: cv::fastFree(void*) (in /opt/ros/fuerte/lib/libopencv_core.so.2.4.2)
==32750==    by 0x807DE6A: boost::detail::function::void_function_invoker1<void (*)(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&), void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (function_template.hpp:112)
==32750==    by 0x4759603: image_transport::RawSubscriber::internalCallback(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&) (function_template.hpp:1013)
==32750==    by 0x4756802: boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void, boost::_mfi::mf2<void, image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&>, boost::_bi::list3<boost::_bi::value<image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >*>, boost::arg<1>, boost::_bi::value<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> > > >, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (mem_fn_template.hpp:280)
==32750==    by 0x474C965: boost::detail::function::void_function_obj_invoker1<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)>, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> >::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const>) (function_template.hpp:1013)
==32750==    by 0x475FBFE: ros::SubscriptionCallbackHelperT<boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, void>::call(ros::SubscriptionCallbackHelperCallParams&) (function_template.hpp:1013)
==32750==    by 0x4128C06: ros::SubscriptionQueue::call() (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40D8A86: ros::CallbackQueue::callOneCB(ros::CallbackQueue::TLS*) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40DA563: ros::CallbackQueue::callAvailable(ros::WallDuration) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x411039A: ros::spinOnce() (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x48FF4D2: (below main) (libc-start.c:226)
==32750== 
==32750== Invalid read of size 4
==32750==    at 0x43EE3C7: cv::fastFree(void*) (in /opt/ros/fuerte/lib/libopencv_core.so.2.4.2)
==32750==    by 0x80779AF: boost::detail::shared_count::~shared_count() (shared_count.hpp:217)
==32750==    by 0x8078991: boost::shared_ptr<cv_bridge::CvImage>::~shared_ptr() (shared_ptr.hpp:168)
==32750==    by 0x8073F2C: ImageCb(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (state_sensor.cpp:185)
==32750==    by 0x807DE6A: boost::detail::function::void_function_invoker1<void (*)(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&), void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (function_template.hpp:112)
==32750==    by 0x4759603: image_transport::RawSubscriber::internalCallback(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&) (function_template.hpp:1013)
==32750==    by 0x4756802: boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void, boost::_mfi::mf2<void, image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&>, boost::_bi::list3<boost::_bi::value<image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >*>, boost::arg<1>, boost::_bi::value<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> > > >, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (mem_fn_template.hpp:280)
==32750==    by 0x474C965: boost::detail::function::void_function_obj_invoker1<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)>, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> >::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const>) (function_template.hpp:1013)
==32750==    by 0x475FBFE: ros::SubscriptionCallbackHelperT<boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, void>::call(ros::SubscriptionCallbackHelperCallParams&) (function_template.hpp:1013)
==32750==    by 0x4128C06: ros::SubscriptionQueue::call() (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40D8A86: ros::CallbackQueue::callOneCB(ros::CallbackQueue::TLS*) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40DA563: ros::CallbackQueue::callAvailable(ros::WallDuration) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==  Address 0x1c8cd31c is 12 bytes inside a block of size 921,624 free'd
==32750==    at 0x402C06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32750==    by 0x43EE3D1: cv::fastFree(void*) (in /opt/ros/fuerte/lib/libopencv_core.so.2.4.2)
==32750==    by 0x807DE6A: boost::detail::function::void_function_invoker1<void (*)(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&), void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (function_template.hpp:112)
==32750==    by 0x4759603: image_transport::RawSubscriber::internalCallback(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&) (function_template.hpp:1013)
==32750==    by 0x4756802: boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void, boost::_mfi::mf2<void, image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&>, boost::_bi::list3<boost::_bi::value<image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >*>, boost::arg<1>, boost::_bi::value<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> > > >, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (mem_fn_template.hpp:280)
==32750==    by 0x474C965: boost::detail::function::void_function_obj_invoker1<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)>, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> >::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const>) (function_template.hpp:1013)
==32750==    by 0x475FBFE: ros::SubscriptionCallbackHelperT<boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, void>::call(ros::SubscriptionCallbackHelperCallParams&) (function_template.hpp:1013)
==32750==    by 0x4128C06: ros::SubscriptionQueue::call() (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40D8A86: ros::CallbackQueue::callOneCB(ros::CallbackQueue::TLS*) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40DA563: ros::CallbackQueue::callAvailable(ros::WallDuration) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x411039A: ros::spinOnce() (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x48FF4D2: (below main) (libc-start.c:226)
==32750== 
==32750== Invalid free() / delete / delete[] / realloc()
==32750==    at 0x402C06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32750==    by 0x43EE3D1: cv::fastFree(void*) (in /opt/ros/fuerte/lib/libopencv_core.so.2.4.2)
==32750==    by 0x80779AF: boost::detail::shared_count::~shared_count() (shared_count.hpp:217)
==32750==    by 0x8078991: boost::shared_ptr<cv_bridge::CvImage>::~shared_ptr() (shared_ptr.hpp:168)
==32750==    by 0x8073F2C: ImageCb(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (state_sensor.cpp:185)
==32750==    by 0x807DE6A: boost::detail::function::void_function_invoker1<void (*)(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&), void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (function_template.hpp:112)
==32750==    by 0x4759603: image_transport::RawSubscriber::internalCallback(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&) (function_template.hpp:1013)
==32750==    by 0x4756802: boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void, boost::_mfi::mf2<void, image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&>, boost::_bi::list3<boost::_bi::value<image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >*>, boost::arg<1>, boost::_bi::value<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> > > >, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (mem_fn_template.hpp:280)
==32750==    by 0x474C965: boost::detail::function::void_function_obj_invoker1<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)>, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> >::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const>) (function_template.hpp:1013)
==32750==    by 0x475FBFE: ros::SubscriptionCallbackHelperT<boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, void>::call(ros::SubscriptionCallbackHelperCallParams&) (function_template.hpp:1013)
==32750==    by 0x4128C06: ros::SubscriptionQueue::call() (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40D8A86: ros::CallbackQueue::callOneCB(ros::CallbackQueue::TLS*) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==  Address 0x1c8cd310 is 0 bytes inside a block of size 921,624 free'd
==32750==    at 0x402C06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32750==    by 0x43EE3D1: cv::fastFree(void*) (in /opt/ros/fuerte/lib/libopencv_core.so.2.4.2)
==32750==    by 0x807DE6A: boost::detail::function::void_function_invoker1<void (*)(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&), void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (function_template.hpp:112)
==32750==    by 0x4759603: image_transport::RawSubscriber::internalCallback(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&) (function_template.hpp:1013)
==32750==    by 0x4756802: boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void, boost::_mfi::mf2<void, image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> const&>, boost::_bi::list3<boost::_bi::value<image_transport::SimpleSubscriberPlugin<sensor_msgs::Image_<std::allocator<void> > >*>, boost::arg<1>, boost::_bi::value<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)> > > >, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&) (mem_fn_template.hpp:280)
==32750==    by 0x474C965: boost::detail::function::void_function_obj_invoker1<boost::function<void ()(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)>, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> >::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const>) (function_template.hpp:1013)
==32750==    by 0x475FBFE: ros::SubscriptionCallbackHelperT<boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, void>::call(ros::SubscriptionCallbackHelperCallParams&) (function_template.hpp:1013)
==32750==    by 0x4128C06: ros::SubscriptionQueue::call() (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40D8A86: ros::CallbackQueue::callOneCB(ros::CallbackQueue::TLS*) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x40DA563: ros::CallbackQueue::callAvailable(ros::WallDuration) (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x411039A: ros::spinOnce() (in /opt/ros/fuerte/lib/libroscpp.so)
==32750==    by 0x48FF4D2: (below main) (libc-start.c:226)
==32750== 
4

0 回答 0