指针和Vector元素的问题——从STL底层的扩容说起

最近在做一个Qt项目,中间有一个业务,从外部xml文件导入,并生成两类对象——单元和平台。
单元和平台相互绑定,多个单元对应一个平台,并且需要在全局数据结构中存储所有单元和所有平台的对象。

初始解决方案:

平台在全局数据中用一个QVector容器来存储。
在单元对象中存储一个平台对象的指针,导入单元对象时,初始化该指针指向QVector容器中的平台对象

问题:

功能上线后,其他的开发同学告诉我,取这个指针好像会取到野指针……?
遂一步步排查

排查:

首先用Qt的Debug模式重现导入过程,导入第一个和第二个单元的时候,一切正常,指针指向的地址与容器里元素的地址一致,也能访问到目标元素——单元所绑定的平台

在这里插入图片描述
但是当全部导入完的时候,平台容器首位的地址就变了!
首个元素的地址从c6778变成了e37c8,原来指向c6778的指针变成野指针了!

在这里插入图片描述
其实这个时候发现Vector往后整体移动就已经在怀疑是不是扩容时内存重分配了,而使我更确定这个结论的地方是上图最后一个导入的单元——它的平台指针指向的地址跟最后一个注册的平台对象还是一致的!这个指针居然没有变成野指针!

众所周知,STL的Vector在插入元素时可能导致扩容,申请更大的一片连续内存空间进行存储,并把原有的部分整体迁移到新的内存空间中,因为我是一遍导入单元对象一边生成平台对象的,每个单元对象在导入完成时就会绑定平台对象,如果QVector容器中找不到要绑定的平台对象,就新建一个放进QVector容器中,所以在导入到一半的时候,新建平台放进QVector容器就可能会触发这个机制,导致前面已绑定的指针全部失效OTZ

解决

第一种方法

在导入所有单元,在QVector容器存好所有平台对象后再统一进行绑定工作,但未来如果别处再对QVector容器进行插入导致扩容的话,野指针还是会出现

第二种方法

绑定的时候不使用指针,而是依赖类似于ID的机制进行绑定,在单元对象中存储平台的ID而非平台对象的指针

第三种方法

把Vector改为链表,链表插入元素的时候不会导致整体移动

由于别的模块已经在使用该容器和指针绑定关系,第二和第三种方法虽然能根除问题,但是导致的改动牵引会比较大,暂时用第一种方法做补救,后续有时间再联合相关模块的人员统一改动

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值