c++ - 个别实例有效,但数组显示内存损坏

标签 c++ arrays ubuntu boost shared-ptr

我遇到了一个奇怪的问题,它与 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_cloudboost::shared_ptr 分配的属性.

为什么会有这种奇怪的行为?访问boost::shared_ptr是否属于非法用例?有什么建议吗?

PS:我在 Ubuntu 14.04 LTS 64 位 PC 上使用 ROS Indigo。

最佳答案

PointCloudSubscriber 可能已损坏1。与其创建 PointCloudSubscriber 的两个默认实例 (1)2 然后为它们分配“真实”值 (2)2,不如执行以下操作:

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

1) 看起来它处理资源,但只定义了一个用户提供的构造函数。你应该观察 the rule of 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)

关于c++ - 个别实例有效,但数组显示内存损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50410564/

相关文章:

c++ - 统一迭代 std::vector<T> 和 std::vector<unique_ptr<T>>

javascript - 如何根据填充数组动态填充值数组?

oracle - 字符编码问题 - Oracle SQL

c++ - c 从 uint64 到 float64_IEEE 的转换?

c++ - gcc 链接器获取未使用对象的列表

c++ - 具有连续内存的结构中的动态数组?

arrays - mongodb - 如果数组中的元素之一与查询匹配,则忽略文档

ubuntu - VS Code 未在 WSL -2 Ubuntu 18.04 服务器中打开 - 未找到命令 'code'

linux - 在 ubuntu 14 上安装 ScyllaDB 期间无法找到软件包 libsystemd-dev

c++ - C++ 中的 I/O 运算符重载错误