首页 > 解决方案 > 带 bo​​ost::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 等的这一点上使用它......)

稍后我将尝试添加一些测试代码...

标签: c++segmentation-faultpoint-cloud-libraryeigen3linux-mint

解决方案


我有两个想法。为了解决您的故障问题,也许为该 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);

让我们知道这些选项中的任何一个是否适合您!


推荐阅读