Protobuf c++使用小坑(set_allocated函数)
protobuf是后台开发中,比较常用的数据通信协议。相对于json,具有数据压缩率高等优点。但是,在某些情况下,稍不留神容易用错。
最近使用protobuf的时候,使用了相对陌生的复合类型的赋值。结果用错了,然后就莫名其妙core dump了。
使用的数据类型简化如下:
- message Answer
- {
- optional uint32 choice = 1;
- optional uint32 id = 2;
- }
- message Detail
- {
- optional Answer answer = 1;
- optional uint32 id = 2;
- }
- message Rsp
- {
- repeated Detail detail = 1;
- }
- message Info
- {
- repeated Answer answer = 1
- }
大概的使用过程是这样的:需要在一个for循环里面,把一个Class中的每一个student拷贝到一个局部的Family对象中的owner中。查看了protoc生成的pb.h文件之后,发现有一个set_allocated_owner(::Person* person)这样的函数。所以,我就使用了如下的代码:
- //info 是一个已经定义好的Info对象
- Rsp rsp;
- for(int index = 0;index<info.answer_size();index++)
- {
- Detail * detail = rsp.add_detail();
- Answer temp_ans = info.answer(index);
- detail.set_allocated_answer(&temp_ans);
- }
- //do something with rsp
然后就coredump了,用gdb调试的时候,发现一堆和protobuf相关的东西,猜测应该是protobuf用错了,但是想了很久都没有想到是什么。
但是凭借直觉,这种coredump一般都是和指针相关,想到也就这个地方用了指针,就果断google了一发protobuf的set_allocated相关的函数,发现果然是用错了。
看到了这篇文章:http://blog.csdn.net/xiaxiazls/article/details/50118161
主要的意思就是,那个temp_ans是局部变量,会在for循环中一个循环结束之后被析构的,然而,set_allocated_answer中放进去的是这个局部变量的指针。所以,后面这个rsp使用的时候,里面的detail的answer的指针已经指向了非法的内存空间了。coredump妥妥的。
如果需要使用set_allocated这种方法,参数里面的指针需要指向一个在使用到这个数据的时候还没有被析构的对象(好绕口)。例如,那个指针参数是new 出来的,或者是在一个更外层的嵌套中定义的。但是,protobuf中会负责析构这个传进去的指针指向的对象,所以,最好传进去一个new出来的对象的地址,因为如果传进去一个原来就定义好的对象的地址,可能因为这个析构,而导致原有对象失效,造成一些潜在的问题(set_allocated_xxx中的allocated已经表明,最好是那种分配出来的对象)
像上面的例子,进行复合类型的赋值,用copyFrom比较好,例子如下:
- Rsp rsp;
- for(int index = 0;index<info.answer_size();index++)
- {
- Detail * detail = rsp.add_detail();
- Answer* ans = detail->mutable_answer();
- Answer temp_ans = info.answer(index);
- ans->copyFrom(temp_ans);
- }
- //do something with rsp
Protobuf c++使用小坑(set_allocated函数)相关推荐
- Python正则表达式中使用findall函数遇到括号嵌套的小坑
1.findall函数 我们都知道括号在正则表达式中起到了分类的作用,但当定义好一个自己的字符匹配模式(含有括号)后,使用findall()函数会遇到一点小坑. 具体来说就是: 可以发现是否将整个正则 ...
- spring + maven项目 互相依赖的小坑
在项目的搭建的过程中,出现了某个被依赖的项目,打包都是成功的,但是依赖的它的项目在编译的时候出现了问题,综合网上的解决方案,终于找到了一个可行的方法. 摘自 https://blog.csdn.net ...
- c++ tinyxml2 解析xml小坑
如题,项目中遇到的解析xml小坑: xml是python在windows下生成的,虽然是utf8的,但是回车是16进制显示的0D 0A,与linux下的回车不同(0A),导致使用Parse函数时解析失 ...
- mysql内核测试,MySQL 5.7内核复制中的一个小坑
问题背景 最近在写一个作为MySQL Slave的角色的程序,连接到MySQL Master使用MySQL复制协议来Dump Binlog事件流.很自然,这个程序在第一次运行的时候,其事务GTIDSe ...
- 微信小程序云函数服务器,微信小程序云函数使用的几点说明
微信小程序云函数是一个好东西,相当于微信为我们提供了一个可以跑node.js的服务器,并且可以外部通过API的方式调用云函数,不过微信的文档一向写的不明不白,初学的时候踩了不少坑,在这里记录下来. 1 ...
- 项目_MySQL比较字符大小的小坑
MySQL字符比较大小的小坑 0.前言 最近在帮学校做一个项目管理类的系统,我就大概说明一个哈,我们在t_project表中,存在一个varchar类型的project_state字段,用于记录目前该 ...
- js创建二维数组小坑
今天在创建一个二维数组时,遇到一个小坑,最后发现是对forEach函数的理解不够深刻导致的bug,特此记录说明. 需求如下:创建一个10 x 10的二维数组 最常规的想法是,进行遍历循环 let it ...
- 【dart】private 小坑
[dart]private 小坑 今天在看dart相关,发现dart里居然没有private/protected/public等权限修饰符,但是要实现private,只需要将需要修饰的字段或者方法,加 ...
- CESIUM学习—— viewer.trackedEntity小坑坑
在使用ceiusm时,或多或少都会用到viewer.trackedEntity这个属性.主要是把相机绑定到entity实例上,如果entity运动的话,还可很方便地实现动画效果.但我在开发中踩过一个小 ...
最新文章
- hdu5701-中位数计数
- Tomcat的manager APP设置
- 浅谈Windows Phone 7的体系结构 - [WP开发文档翻译系列]
- 语言课程设计超市售货_自闭症儿童家庭干预10个语言能力提升小技巧
- 深入理解Java类加载机制
- G - Eating Plan
- 【BZOJ - 3436】小K的农场(差分约束)
- 计算机c盘丢失,电脑C盘丢失的视频文件怎么恢复?方法讲解,轻松搞定
- linux编程之指针
- 2021最新 武汉互联网公司
- 生鲜电商:卖什么?卖给谁?怎么卖?
- CSS3---移动端苹果安卓适配
- 安卓Android手机校园外卖订餐系统毕业设计
- 蓝桥 密码锁(Java)
- 安装vray显示指定服务器没安装,安装vray是出现“不是有效的win32应用程序”怎么回事?...
- Pytest3种配置文件方式
- ANDROID 11 文件系统挂载
- Linux多线程——生产者消费者模型
- ubuntu14.04搭建smba共享
- 百度地图自定义标注点
热门文章
- el table 固定表头和首行_表头太太太复杂了,如何批量打印?简单!
- mac android 证书生成工具,MAC系统下,生成安卓证书的命令
- vmci.sys版本不正确_王者荣耀:当前版本辅助的正确玩法思路,别再被骂,也别再梦游了...
- 图像处理之特征描述与匹配
- 兼容最新PS2021 Raya Pro 5 for Mac——值得推荐的PS终极数字混合扩展面板
- 信奥中的数学:计算几何
- STM32H743+CubeIDE-CanFestival实现两个CANopen Master同时独立运行
- python mysql 内存_Python将系统内存使用量写入mysql数据库
- 计算机报名忻州考点,2020山西省考忻州考区考点安排
- 汇知考轻松职称计算机辅导软件,汇知考轻松