使用memcpy()时报错

找了两个小时的问题,记录一下, 在ROS下usb_cam节点下添加了新的去畸变函数,并将其发布成topic,但是在实际运行的时候,有时候会出现段错误,debug模式提示如下:

__memcpy_avx_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S:238

可以定位到我代码中的memcpy()函数, 其实是ROS下的sensor_msgs::fillmage()的

memcpy(&image.data[0], data_arg, st0);

用gdb调试了解到,这里是将data_arg中的内容拷贝到image.data中时,出现data_arg这块内存无法访问, 而data_arg其实是一个cv::Mat的data;

由此定位到了这段函数:

void UsbCam::undistort_image()
{
  cv::Mat ori_img,dst_img;
  int img_size; 
  if(monochrome_){
   ori_img=cv::Mat(image_->height,image_->width,CV_8UC1,image_->image);
   img_size = image_->width*image_->height;
  }else
  {
   ori_img=cv::Mat(image_->height,image_->width,CV_8UC3,image_->image);
   img_size = image_->width*image_->height*3;
  }
  cv::remap(ori_img,dst_img,mat_mapx,mat_mapy,cv::INTER_LINEAR);
  undistort_image_->width = dst_img.cols;
  undistort_image_->height = dst_img.rows;
 undistort_image_->image = reinterpret_cast<char*>(dst_img.data);
  if(dst_img.empty())
      ROS_INFO_STREAM("dst_img is empty ");
}

上面的函数定义了 ori_img 和 dst_img两个cv::Mat, 对ori_img在赋值之后进行了去畸变操作,去畸变后的图像保存在dst_img中,随后又将dst_img的图像数据,即data保存到undistort_image->image中,但是这里的保存仅仅是将undistort_image->image的指针指向了ori_img.data的地址,并没有进行内存的拷贝,同时dst_img又是这个函数的局部变量,在退出该函数的时候cv::Mat的析构函数会自动释放dst_img对应的内存,因此,等到外面在访问这块内存进行memcpy的操作时,会出现访问不到内存,导致memcpy出错。

这里的修改方式为将 

undistort_image_->image = reinterpret_cast<char*>(dst_img.data);

修改为:

  memcpy(&undistort_image_->image[0], dst_img.data, img_size);

将内存通过memcpy拷贝进来,从而避免dst_img的内存被释放时,也相当于释放了undistort_image->image对应的内存; 同时我的undistort_image->image因为是事先申请好了一块内存的, 就应该进行这样的深拷贝,而不是直接将将指针指向对应的地址;

关于深拷贝和浅拷贝参考C++的深拷贝和浅拷贝; 对于像cv::Mat这样的类,其中的data中的数据(指针类型),只有执行深拷贝,才能保证新保存的数据与Mat中的data相互独立,否则,一旦元数据被释放,新保存的数据也不存在了; 

当然,我这里的根源问题,并不在于memcpy(), 而是在于错误地将指针指向局部变量的内存地址, 如果有小伙伴在使用memcpy()时出现了问题,也可以试一下将memcpy()替换掉,自己写一个for循环进行拷贝,看一下还会不会有错;

这是我中间的debug过程,发出来分享一下:

    image.data.resize(st0);
    image.data.clear();//将我原来为image.data申请的内存先清除掉
    char *pdata = (char *)data_arg;//做一个类型转换,不重要
    printf("image.data = %d   %d %d \n", &image.data[0], image.data.capacity(), data_arg);
    for (size_t i = 0; i < st0; i++)
    { 
        image.data.push_back((char)pdata[i]);//替换memcpy(),自己手动copy
    }

不一定能解决问题,但是可以作为一个Debug的思路。

:)

 

 

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值