共享指针超出循环范围时出错(堆损坏?)

Fre*_*red 1 c++ qt boost heap-corruption point-cloud-library

我通过逐行逐步执行代码找不到问题.

我设法从代码库中提取了一个最小的例子,它归结为以下几行.代码的作用是从对象读取3D点云,将其包装到共享指针中并使用QT的信号引擎将其发送出去.中间的两行导致错误:

for(vector<Package>::iterator resit = results.begin(); resit != results.end(); resit++) {
    // [..] Code ommitted
    pcl::PointCloud<pcl::PointXYZ> c = queryObject.getCloud();


    // The Ptr typedef resolves to boost::shared_ptr<PointCloud<PointT>>
    // (1) Does not work:   
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr(&c);
    // (2) Works:
    //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);


    emit this->cluster_added(cloud_ptr);
}
// The error always happens AFTER the FIRST iteration
Run Code Online (Sandbox Code Playgroud)

当我在(2)中发表评论(当然评论出(1)时),代码有效.在这两个版本中cloud_ptr都是一个携带云的共享指针 - 除了第一次它是一个填充的云而不是第二个版本的事实.

编辑:既然你们指出了 - 我看到当前版本搞砸了.这是无意义的试用的结果.最初,该getCloud()方法返回了指向云的指针.但那个版本也不起作用.这是代码的原始版本:

for(vector<Package>::iterator resit = results.begin(); resit != results.end(); resit++) {
    // [..] Code ommitted

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr(queryObject.getCloud());


    emit this->cluster_added(cloud_ptr);
}
Run Code Online (Sandbox Code Playgroud)

编辑#2:解决方案

原来我对增强指针有很大的误解.这里正确的方法是创建指针和点云,然后将事物传递给对象:

// Object creation
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
// Do some loading..
[..]

// Use the cloud in the for loop
emit this->cluster_added(queryObject.getCloud());
Run Code Online (Sandbox Code Playgroud)

Heaperror2 Heaperror1

Tar*_*ama 8

你的问题是在这里创建一个堆栈分配的变量:

pcl::PointCloud<pcl::PointXYZ> c = queryObject.getCloud();
Run Code Online (Sandbox Code Playgroud)

当该变量超出范围时,它将被销毁,因此将其包装成一个std::shared_ptr没有意义.

你如何解决这个问题取决于你的PointCloud类在复制方面的语义,但我猜想使用这一行会解决这个问题:

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>(c));
Run Code Online (Sandbox Code Playgroud)

或者,如果您不希望指针类型发生变化:

auto cloud_ptr = {make_shared<pcl::PointCloud<pcl::PointXYZ>>(c)};
Run Code Online (Sandbox Code Playgroud)