析构函数中释放内存时crash - free(): invalid size / free(): invalid pointer / double free or corruption(out)

在处理一个仅在Release版本复现的App Crash问题时,通过QtCreator调试发现异常发生在析构函数中释放指针时。通过分析函数调用栈,定位到特定代码段,发现两个栈对象可能导致问题。通过添加日志输出,确定了非法指针,并进一步通过对比栈对象地址找到问题源。最后,检查可能的指针自增操作,成功定位并解决了问题。
摘要由CSDN通过智能技术生成

原因
1.通常是有指针越界造成的,仔细检查代码有没有越界的行为。
2.指针在程序运行中位置发了变化,例如指针a,执行了a++操作。

最近在处理一个 App crash的问题时,异常诡异,仅仅在release版本下可以复现(但不是必现),debug版本不能复现。好在用QtCreator通过debug跑release版本的代码时可以截取到crash时的函数调用栈。函数调用栈显示在一个析构函数中free某一个地址的时候出的问题。
在这里插入图片描述
这样就大大缩小了搜索的范围,问题就定位在第7行的函数中析构第6行的类对象的时候。所以有两个出发点:

  1. Check第7行的函数实现,发现函数中一共有两个地方定义了该类的对象(均为栈对象),既然不是用new分配的内存,那么只有一种可能,就是在代码块结束或者整个函数返回时依次释放栈对象的时候析构的。
  2. Check第6行析构函数,发现有很多释放结构体指针(数组)的代码,release模式的代码无法加断点(加了也不会停),无法具体定位到是在释放哪个指针的时候出的错。只有一个方法,修改这两个函数文件所在的pro文件,在release分支中删除DEFINES += QT_NO_DEBUG_OUTPUT QT_NO_WARNING_OUTPUT,以允许release模式的log输出,然后依次在上图析构函数中加log(log加多了不容易复现,所以依次加一两个)逐步确认到在倒数第二行出现非法指针(为了描述方便,假设这个指针是obj->struct1)。

这样,虽然知道了哪个指针是非法的,但是上图第7行函数中有两个地方定义了该类的栈对象,不好判断是哪个栈对象出的问题。方法仍然是加log,在这两个栈对象定义的下一行,分别输出一行log,打印出obj->struct1的地址,有了这个地址,就可以结合crash log, 进行对比。最终定位到第二个栈对象, 发现二者有0x2000的offset。
在这里插入图片描述
所以定位在检查使用obj->struct1的时候,哪些地方有可能做指针++的动作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值