栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

初始解决方案:

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

问题:

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

排查:

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


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


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

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

解决 第一种方法

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

第二种方法

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

第三种方法

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

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

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1037841.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号