当前位置:   article > 正文

【未解决:问题记录:】PCL中Ptr错误:已触发了一个断点。

【未解决:问题记录:】PCL中Ptr错误:已触发了一个断点。

在学习PCL官方文档Filtering一节中,或者学习《点云库PCL从入门到精通》的第六章第6.2.1节使用直通滤波器对点云进行滤波处理时,会有如下代码报错。

  1. #include <iostream>
  2. #include <ctime>
  3. #include <pcl/point_types.h>
  4. #include <pcl/filters/passthrough.h>
  5. int
  6. main (int argc, char** argv)
  7. { srand(time(0));
  8. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  9. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
  10. //填入点云数据
  11. cloud->width = 5;
  12. cloud->height = 1;
  13. cloud->points.resize (cloud->width * cloud->height);
  14. for (size_t i = 0; i < cloud->points.size (); ++i)
  15. {
  16. cloud->points[i].x = rand () / (RAND_MAX + 1.0f)-0.5;
  17. cloud->points[i].y = rand () / (RAND_MAX + 1.0f)-0.5;
  18. cloud->points[i].z = rand () / (RAND_MAX + 1.0f)-0.5;
  19. }
  20. std::cerr << "Cloud before filtering: " << std::endl;
  21. for (size_t i = 0; i < cloud->points.size (); ++i)
  22. std::cerr << " " << cloud->points[i].x << " "
  23. << cloud->points[i].y << " "
  24. << cloud->points[i].z << std::endl;
  25. // 创建滤波器对象
  26. pcl::PassThrough<pcl::PointXYZ> pass;
  27. pass.setInputCloud (cloud);
  28. pass.setFilterFieldName ("z");
  29. pass.setFilterLimits (0.0, 1.0);
  30. //pass.setFilterLimitsNegative (true);
  31. pass.filter (*cloud_filtered);
  32. std::cerr << "Cloud after filtering: " << std::endl;
  33. for (size_t i = 0; i < cloud_filtered->points.size (); ++i)
  34. std::cerr << " " << cloud_filtered->points[i].x << " "
  35. << cloud_filtered->points[i].y << " "
  36. << cloud_filtered->points[i].z << std::endl;
  37. return (0);
  38. }

运行错误为:

 定位一下free看看

 问题描述:free(ptr)出错。free,没看懂,但是ptr是   

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

 中的Ptr,按住ctrl,追踪Ptr

 追踪这个shared_ptr

 找了这个类的析构函数

 析构函数调用_Decref():追踪这个函数。找到一个Destory()。差不多找到了。

 追踪这个_Destory

还是看不懂了。

 但是至此我们大概猜到:是我们对只能共享指针Ptr使用不对。

我们上网搜索:还真找到了

对方在stackOverflow上的代码如下:

  1. #include <pcl/io/pcd_io.h>
  2. #include <pcl/point_types.h>
  3. #include <pcl/visualization/pcl_visualizer.h>
  4. #include <boost/thread/thread.hpp>
  5. using namespace std;
  6. int main(int argc, char** argv) {
  7. pcl::PointCloud<pcl::PointXYZRGB> cloud;
  8. // Fill in the cloud data
  9. cloud.width = 10000;
  10. cloud.height = 1;
  11. cloud.is_dense = false;
  12. cloud.points.resize(cloud.width * cloud.height);
  13. for (size_t i = 0; i < cloud.points.size(); ++i) {
  14. cloud.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
  15. cloud.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
  16. cloud.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
  17. cloud.points[i].r = 256 * rand() / (RAND_MAX + 1.0f);
  18. cloud.points[i].g = 256 * rand() / (RAND_MAX + 1.0f);
  19. cloud.points[i].b = 256 * rand() / (RAND_MAX + 1.0f);
  20. }
  21. //pcl::io::savePCDFileASCII("testpcd.pcd", cloud);
  22. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(&cloud);
  23. //visualiser
  24. boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
  25. viewer->setBackgroundColor(0, 0, 0);
  26. viewer->addPointCloud<pcl::PointXYZRGB>(cloud_ptr, "sample cloud");
  27. viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
  28. viewer->addCoordinateSystem(1.0);
  29. viewer->initCameraParameters();
  30. //viewer->resetCameraViewpoint("sample cloud");
  31. while (!viewer->wasStopped())
  32. {
  33. viewer->spinOnce(100);
  34. boost::this_thread::sleep(boost::posix_time::microseconds(100000));
  35. }
  36. return (0);
  37. }

 运行错误如下:与我们的略有不同。

先看解决方案:

原文

You are taking a pointer to an object on the stack, and handing it to a shared pointer.

At the end of the scope, the shared pointer destructor then attempts to free up that memory (which it cannot do since it is on the stack, not the heap).

Try something like this instead:

试着翻译一下:

将指向栈上对象的指针传递给共享指针。在作用域的末尾,共享指针析构函数然后尝试释放该内存(它不能这样做,因为它是在栈上,而不是在堆上)。试着这样做:

我们按照这个方法修改试试。

  1. //pcl::PointCloud<pcl::PointXYZRGB> cloud;
  2. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);

 将cloud变量生命在了堆中。Ptr是一个共享指针,所以调用其属性,需要用->。代码修改如下。

  1. #include <pcl/io/pcd_io.h>
  2. #include <pcl/point_types.h>
  3. #include <pcl/visualization/pcl_visualizer.h>
  4. #include <boost/thread/thread.hpp>
  5. using namespace std;
  6. int main(int argc, char** argv) {
  7. //pcl::PointCloud<pcl::PointXYZRGB> cloud;
  8. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
  9. // Fill in the cloud data
  10. cloud->width = 10000;
  11. cloud->height = 1;
  12. cloud->is_dense = false;
  13. cloud->points.resize(cloud->width * cloud->height);
  14. for (size_t i = 0; i < cloud->points.size(); ++i) {
  15. cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f); // 属性调用由.变->
  16. cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f); // 属性调用由.变->
  17. cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
  18. cloud->points[i].r = 256 * rand() / (RAND_MAX + 1.0f);
  19. cloud->points[i].g = 256 * rand() / (RAND_MAX + 1.0f);
  20. cloud->points[i].b = 256 * rand() / (RAND_MAX + 1.0f);
  21. }
  22. //pcl::io::savePCDFileASCII("testpcd.pcd", cloud);
  23. //pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(&cloud); // 原来这样,
  24. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(cloud); // 这里要修改。
  25. //visualiser
  26. boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
  27. viewer->setBackgroundColor(0, 0, 0);
  28. viewer->addPointCloud<pcl::PointXYZRGB>(cloud_ptr, "sample cloud");
  29. viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
  30. viewer->addCoordinateSystem(1.0);
  31. viewer->initCameraParameters();
  32. //viewer->resetCameraViewpoint("sample cloud");
  33. while (!viewer->wasStopped())
  34. {
  35. viewer->spinOnce(100);
  36. boost::this_thread::sleep(boost::posix_time::microseconds(100000));
  37. }
  38. return (0);
  39. }

注意:这里这样修改。问题解决了。

  1. //pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(&cloud); // 原来这样,
  2. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(cloud); // 这里要修改。

我把问题凝练了一下,省去多余代码:总结为如下四行代码的问题:

 

  1. #include <pcl/io/pcd_io.h>
  2. #include <pcl/point_types.h>
  3. int main(int argc, char** argv) {
  4. // 这两行会报错。 // 因为cloud_ptr开辟在了栈中。
  5. pcl::PointCloud<pcl::PointXYZRGB> cloud;
  6. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(&cloud);
  7. // 改成这两行才可以跑通。 // ptr开辟在堆中。
  8. //pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
  9. //pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(cloud);
  10. return (0);
  11. }
  12. // 上面两行会报错:02 滤波.exe 已触发了一个断点。
  13. // void _Decref() noexcept { // decrement use count
  14. //if (_MT_DECR(_Uses) == 0) {
  15. // _Destroy(); // 错误定位在这里。
  16. // _Decwref();
  17. //}
  18. // }
  19. // 改正方法:参照这个:
  20. // https://stackoverflow.com/questions/38090862/pcl-visualizer-exception-thrown-from-eigen-when-exit-visualizer-window
  21. // 将Ptr智能指针开辟在堆中。
  22. // 然后把这个指针变量直接丢给新的构造函数。这样就没问题了。新的Ptr开辟在堆中。

我们再回来解决我们自己的问题。

我们可以把我们自己的代码也凝练,但是,我们发现代码中使用的cloud都已经是Ptr类型。而且也都是通过new的方式,开辟在了堆中。

转一圈,还是没解决我们自己的问题。

问题:记录:改日重新攻克。目前的想到是:try然后放弃。或者手动释放。不知道linux系统下如何?

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/427576
推荐阅读
相关标签
  

闽ICP备14008679号