c++ - 带 boost::make_shared / eigen3 memory.h 的 SEG FAULT
问题描述
我在下面的代码中遇到了分段错误。但是,这只发生在我的 Mint 19 系统上运行 gcc 7.3 和 boost 1.65、PCL 1.8.1、Eigen3.4.4 在我的其他系统上(运行 Ubuntu 16.04、gcc 5.4、boost 1.58、1.8.0、Eigen3.3 beta1-2 ) 不会发生此运行时错误。
我已经在调试模式下跟踪错误。奇怪的是,函数代码一直执行到最后,然后调试器将函数向上跳转到该行
typename pcl::PointCloud<PointT>::Ptr cloudFiltered = boost::make_shared<pcl::PointCloud<PointT> >();
进一步跟踪这个调用,调试器到达 /usr/include/eigen3/Eigen/src/Core/util/Memory.h:
inline void handmade_aligned_free(void *ptr)
{
if (ptr) std::free(*(reinterpret_cast<void**> (ptr) - 1 );
}
这里 SEG FAULT 发生在具有(gcc 7.3、boost 1.65、Eigen3.3.4 和 PCL 1.8.1)的机器上。我有一个解决方法,通过它我将 pcl::PointCloud::Ptr &cloudFiltered 从外部传递给这个函数,并且显然在下面的函数中删除了这个变量的声明。这行得通。但是,这并不是我真正想要的,我在其他功能中也有类似的情况,我不想这样做,我认为一旦达到这一点,也会发生同样的错误......另外,我想了解我在这里做错了什么,而不仅仅是应用热修复......
template <typename PointT>
int
readLAS2PCD(std::string fileToRead,
typename pcl::PointCloud<PointT>::Ptr &cloud,
const float gridLeafSize)
{
// 1) create a file stream object to access the file
std::ifstream ifs;
ifs.open(fileToRead, std::ios::in | std::ios::binary);
// if the LAS file could not be opend. throw an error (using the PCL_ERROR functionality).
if (!ifs.is_open())
{
PCL_ERROR ("Couldn't read file ");
return -1;
}
// set up ReaderFactory of the LibLAS library for reading in the data.
std::cout << "Reading in LAS input file: " << fileToRead << std::endl;
liblas::ReaderFactory f;
liblas::Reader reader = f.CreateWithStream(ifs);
liblas::Header const& header = reader.GetHeader();
long int nPts = header.GetPointRecordsCount();
std::cout << "Compressed: " << (header.Compressed() == true) ? "true\n":"false\n";
std::cout << "\nSignature: " << header.GetFileSignature() << '\n';
std::cout << "Points count: " << nPts << '\n';
// Fill in the PCD cloud data
cloud->width = nPts;
cloud->height = 1;
cloud->is_dense = false;
cloud->points.resize (cloud->width * cloud->height);
int i = 0;
while (reader.ReadNextPoint()){
liblas::Point const& p = reader.GetPoint();
cloud->points[i].x = static_cast<float>( p.GetX() );
cloud->points[i].y = static_cast<float>( p.GetY() );
cloud->points[i].z = static_cast<float>( p.GetZ() );
cloud->points[i].intensity = p.GetIntensity();
if (i % 500000 == 0)
std::cout << i << " x: " << p.GetX() << " y: " << p.GetY() << " z: " << p.GetZ() << "\n";
i++;
}
//here the seg fault happens after the lines below have been executed (on the way out of the function)
typename pcl::PointCloud<PointT>::Ptr cloudFiltered = boost::make_shared<pcl::PointCloud<PointT> >();
if (gridLeafSize > 0.029 && gridLeafSize < 1){
std::cout << "\nApplying Uniform downsampling with leafSize " << gridLeafSize << ". Processing...";
pcl::UniformSampling<PointT> uniform_sampling;
uniform_sampling.setInputCloud (cloud);
uniform_sampling.setRadiusSearch (gridLeafSize); //the 3D grid leaf size
uniform_sampling.filter(*cloudFiltered);
pcl::copyPointCloud(*cloudFiltered, *cloud); // cloud is given by reference so the downsampled cloud has to be copied in there
}
else // else copy original cloud in cloud Filtered and save file...
pcl::copyPointCloud(*cloud,*cloudFiltered);
std::string fileToWrite = fileToRead + ".pcd";
std::cout << "Writing PCD output file: " << fileToWrite << std::endl;
pcl::io::savePCDFile (fileToWrite, *cloudFiltered,true);
std::cerr << "Saved " << cloudFiltered->points.size () << " Points to " << fileToWrite << std::endl;
return (0);
}
编辑:
我以前从未使用过 valgrind,所以我不确定我是否正确使用它。摘要说明或表明可能存在悬空指针。
==11556== LEAK SUMMARY:
==11556== definitely lost: 0 bytes in 0 blocks
==11556== indirectly lost: 0 bytes in 0 blocks
==11556== possibly lost: 1,508,328,093 bytes in 119 blocks
==11556== still reachable: 713,529,397 bytes in 19,422 blocks
==11556== suppressed: 0 bytes in 0 blocks
==11556== Reachable blocks (those to which a pointer was found) are not shown.
==11556== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==11556==
==11556== For counts of detected and suppressed errors, rerun with: -v
==11556== ERROR SUMMARY: 119 errors from 119 contexts (suppressed: 0 from 0)
Aborted (core dumped)
错误报告很长,它出现在各个地方可能会丢失一些字节。同样在许多库函数中(opencv - 我什至没有在代码、Eigen 等的这一点上使用它......)
稍后我将尝试添加一些测试代码...
解决方案
我有两个想法。为了解决您的故障问题,也许为该 cloudFiltered 云分配一些新内存:
typename pcl::PointCloud<PointT>::Ptr cloudFiltered = boost::make_shared<pcl::PointCloud<PointT> >(new pcl::PointCloud<pcl::PointCloud<PointT>>());
有一次我对新云使用 .filter 方法时,云声明如下所示:
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZI>);
另一方面,看起来你可以在不创建新变量的情况下度过难关。如果您达到该 if 语句,只需编辑输入云。尝试:
if (gridLeafSize > 0.029 && gridLeafSize < 1){
std::cout << "\nApplying Uniform downsampling with leafSize " << gridLeafSize << ". Processing...";
pcl::UniformSampling<PointT> uniform_sampling;
uniform_sampling.setInputCloud (cloud);
uniform_sampling.setRadiusSearch (gridLeafSize); //the 3D grid leaf size
uniform_sampling.filter(*cloud); // EDIT. Output cloud is your filtered input cloud
// pcl::copyPointCloud(*cloudFiltered, *cloud); // Do not need to store points in a new variable
}
// EDIT: Else, do nothing to your input cloud. No longer need the else!
//else
// pcl::copyPointCloud(*cloud,*cloudFiltered);
让我们知道这些选项中的任何一个是否适合您!
推荐阅读
- c++ - 为什么不支持 Xcode 1.5?
- javascript - Console.Log输出混乱
- api - 无法使用Vuex存储方法函数
- sql - WHERE 子句中的动态可选参数
- c# - 在相机视图之外生成对象
- java - 当可以证明强制转换是安全的时避免使用@SuppressWarnings("unchecked")
- python - 嵌套循环 - 请解释
- azure - 在现有 Azure Logic App Flow 中调用 Rest API 并处理响应
- javascript - 在 vue.js 中使用 ionicons 5
- python - 为什么存储在networkx图中的边会自动乱序移动?