Ошибка SEG с boost :: make_shared / eigen3 memory.h - PullRequest
0 голосов
/ 18 сентября 2018

Я получаю ошибку сегментации со следующим кодом ниже.Однако это происходит только в моей системе 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 происходит на машине с (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 и т. Д.)

Я постараюсь добавить тестовый код позже ...

1 Ответ

0 голосов
/ 18 сентября 2018

У меня есть две идеи.Чтобы решить вашу проблему с ошибкой, возможно, выделите новую память для этого облака 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);

Сообщите нам, работает ли какой-либо из этих вариантов для вас!

...