首页 > 解决方案 > c++ shared_ptr 断言`px != 0' 失败

问题描述

我想使用线程来并行处理点云。首先,我在调用 fillColoredCloud() 函数之前初始化了一个输出向量 (projected_clouds)。在函数内部,我将点云分配为向量的一个实例。当我尝试在函数之外调用这个向量时,例如:

cout << projected_clouds[0]->points.size(); 

我得到“断言‘px!= 0’失败。” 和我的代码:

auto start1 = std::chrono::high_resolution_clock::now();

std::mutex mutex_;
int num_threads = 12;
std::vector<boost::thread> thread_vec(num_threads);

std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> projected_clouds(num_threads);

for(int i=0; i<num_threads; i++)
{
    const unsigned int  start_index = cloud_in->size()/num_threads*i;
    const unsigned int  end_index = cloud_in->size()/num_threads*(i+1);

    Cloud::Ptr partial_cloud(new Cloud);

    if(i==num_threads-1)
    {
        partial_cloud->points.assign(cloud_in->points.begin()+start_index, cloud_in->points.end());
    }else{
        partial_cloud->points.assign(cloud_in->points.begin()+start_index, cloud_in->points.begin()+end_index);
    }
    thread_vec[i] = boost::thread(boost::bind(&CameraProjection::fillColoredCloud, this, partial_cloud, mat_point_transformer,
                                                      img_size ,reshaped_img, &mutex_, projected_clouds, i));
}

for (auto & iterator : thread_vec) {
    iterator.join();
}
cout << projected_clouds[0]->points.size();

填充彩色云():

void CameraProjection::fillColoredCloud(Cloud::Ptr cloud_in,Eigen::Matrix4d mat_point_transformer,cv::Size img_size,cv::Mat cv_img, std::mutex* mutex_,
                                        std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr>& projected_clouds, int i)
{
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr projected_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);

    for (const auto &point : cloud_in->points)
    {
        auto pair = CameraProjection::pointInImagePlane(point, mat_point_transformer, img_size);
        bool in = pair.first;
        cv::Point point_in_image = pair.second;

        if(in)
        {
            pcl::PointXYZRGB colored_point = CameraProjection::giveColoredPoint(cv_img, point_in_image, point);
            projected_cloud->points.push_back(colored_point);
        }
    }
    projected_clouds[i] = projected_cloud;
    std::cout << "fillColoredCloud() running" << std::endl;
}

错误是:

 /usr/include/boost/smart_ptr/shared_ptr.hpp:734: typename boost::detail::sp_member_access<T>::type boost::shared_ptr<T>::operator->() const [with T = pcl::PointCloud<pcl::PointXYZRGB>; typename boost::detail::sp_member_access<T>::type = pcl::PointCloud<pcl::PointXYZRGB>*]: Assertion `px != 0' failed.

标签: c++shared-ptrsmart-pointerspoint-cloud-library

解决方案


boost::bind应该像这样工作std::bind:它复制其参数。这意味着您的线程实际上正在使用projected_clouds存储在由返回的对象中的副本boost::bind(...),并且原始向量未被触及(它都是默认构造的对象,如果它们是shared_ptrs 将不会指向任何东西)。

使用std::ref(/ boost::ref) 来防止复制(或者像使用互斥锁一样使用指针)

看到您使用的是 C++11,使用 lambda 会更容易:

thread_vec[i] = boost::thread([=, &mutex_, &projected_clouds] {
    fillColoredCloud(partial_cloud, mat_point_transformer, img_size, reshaped_img, &mutex_, projected_clouds, i);
});

推荐阅读