Отдельные экземпляры работают, но массив показывает повреждение памяти - PullRequest
0 голосов
/ 18 мая 2018

Я сталкиваюсь со странной проблемой, связанной с массивами в C ++.По сути, я сделал два экземпляра класса, а затем я использовал эти экземпляры, что вызвало ошибку повреждения памяти.Код работает, если я создаю отдельные два экземпляра этого класса без использования массива вообще.

Пожалуйста, посмотрите фрагмент кода ниже-

int main(int argc, char** argv)
{
    ros::init(argc, argv, "my_node");
    ros::NodeHandle nh("~");

    // this doesn't work
    PointCloudSubscriber pcs[2];
    pcs[0] = PointCloudSubscriber(nh, "/kinect1/sd/points", 1);
    pcs[1] = PointCloudSubscriber(nh, "/kinect2/sd/points", 1);

    // this works
    //PointCloudSubscriber pc1(nh, "/kinect1/sd/points", 1);
    //PointCloudSubscriber pc2(nh, "/kinect2/sd/points", 1);

    ros::Rate loop_rate(10);
    while (ros::ok())
    {
        // this doesn't work
        for (size_t i = 0; i < 2; i++)
          ROS_INFO_STREAM("Cloud topic=" << pcs[i].topic << 
                          ", size=" << pcs[i].point_cloud.data.size());

        // this works
        //ROS_INFO_STREAM("Cloud topic=" << pc1.topic << 
        //                ", size=" << pc1.point_cloud.data.size());
        //ROS_INFO_STREAM("Cloud topic=" << pc2.topic << 
        //                ", size=" << pc2.point_cloud.data.size());

        ros::spinOnce();
        loop_rate.sleep();
    }

    return 0;
}

class PointCloudSubscriber
{
private:
    ros::Subscriber subscriber;
    void callback(
        const sensor_msgs::PointCloud2ConstPtr& msg);

public:
    std::string topic;
    sensor_msgs::PointCloud2 point_cloud;
    PointCloudSubscriber(){};
    PointCloudSubscriber(
        ros::NodeHandle& node_handle,
        std::string topic_name,
        int queue_size);
};

void PointCloudSubscriber::callback(
    const sensor_msgs::PointCloud2ConstPtr& msg)
{
    point_cloud = *msg;
}

PointCloudSubscriber::PointCloudSubscriber(
    ros::NodeHandle& node_handle,
    std::string topic_name,
    int queue_size)
{
    topic = topic_name;
    subscriber = node_handle.subscribe<sensor_msgs::PointCloud2>(
        topic_name, queue_size, &PointCloudSubscriber::callback, this);
}

Ниже приведен результат вывода -

[ INFO] [1526440334.856181149]: Cloud topic=/kinect1/sd/points, size=0
[ INFO] [1526440334.856210465]: Cloud topic=/kinect2/sd/points, size=0
*** Error in `/home/ravi/ros_ws/devel/lib/my_pcl_tutorial/check': double free or corruption (!prev): 0x000000000128f220 ***
Aborted (core dumped)

Интересно отметить, что каждый элемент массива может получить правильный topic, но каким-то образом не может получить атрибут point_cloud, который назначен из boost::shared_ptr.

Почему такое странное поведение?Это незаконный случай использования доступа к boost::shared_ptr?Любые предложения, пожалуйста?

PS: Я использую ROS Indigo на 64-битном ПК Ubuntu 14.04 LTS.

1 Ответ

0 голосов
/ 18 мая 2018

PointCloudSubscriber возможно сломан 1 .Вместо создания двух экземпляров по умолчанию (1) 2 из PointCloudSubscriber и последующего присвоения им «реальных» значений (2) 2 , выполните:

PointCloudSubscriber pcs[2] = {
    PointCloudSubscriber(nh, "/kinect1/sd/points", 1),
    PointCloudSubscriber(nh, "/kinect2/sd/points", 1)
};

1) Похоже, он обрабатывает ресурсы, но определяет только предоставленный пользователем конструктор.Вы должны соблюдать правило 0/3/5 .

2) К вашему сведению, (1) и (2):

PointCloudSubscriber pcs[2]; // (1)
pcs[0] = PointCloudSubscriber(nh, "/kinect1/sd/points", 1); // (2)
pcs[1] = PointCloudSubscriber(nh, "/kinect2/sd/points", 1); // (2)
...