WinDbg delete问题

12 篇文章 3 订阅
9 篇文章 0 订阅

文章目录

1、测试程序如下:

#include "stdafx.h"
#include "CBaseDrvTest.h"

int _tmain(int argc, _TCHAR* argv[])
{

	CBaseDrvTest* pBase = new CBaseDrvTest;
	pBase->Init();
	std::cout << pBase->nValue << std::endl;

	delete pBase;
	pBase->UnInit();
	pBase->nLignt = 111;
	std::cout << pBase->nValue << std::endl;

	system("pause");
	return 0;
}

2、测试时发现测试所用的VS2008有时候也不会触发崩溃,抓取的dump信息如下:

0:000:x86> ~0s; .ecxr ; kb
ntdll_76e90000!NtWaitForMultipleObjects+0xc:
76f032fc c21400          ret     14h
Minidump doesn't have an exception context
Unable to get exception context, HRESULT 0x80004002
ChildEBP RetAddr  Args to Child              
005df0ec 76647ef3 00000003 005df320 00000001 ntdll_76e90000!NtWaitForMultipleObjects+0xc
WARNING: Stack unwind information not available. Following frames may be wrong.
005df280 76647da8 00000003 005df320 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x133
005df29c 75ec6967 00000003 005df320 00000000 KERNELBASE!WaitForMultipleObjects+0x18
005df348 75ec6598 00000000 00000000 005df43c kernel32!WerpReportFaultInternal+0x3b7
005df364 75e9c299 005df40c 766fce6b 005df43c kernel32!WerpReportFault+0x9d
005df36c 766fce6b 005df43c 00000001 5c7948c7 kernel32!BasepReportFault+0x19
005df40c 76f3287e 005df43c 76f072f2 005dfddc KERNELBASE!UnhandledExceptionFilter+0x29b
005dfddc 76ef8774 ffffffff 76f1a120 00000000 ntdll_76e90000!__RtlUserThreadStart+0x3a109
005dfdec 00000000 00f37b48 00763000 00000000 ntdll_76e90000!_RtlUserThreadStart+0x1b

从上面看,没有相关的堆栈信息,接下来按照之前说过的方法操作,得到

dump信息
3、从dump信息看,应该是进程在退出的时候free内存出现了问题,导致了崩溃
提示**“scalar deleting destructor”**,怀疑是指针被delete、或者delete之后还使用了指针,即使用了野指针、或者被释放的内存越界等就会出现这个提示

4、除此之没有其他的信息,但是测试用例相对简单,所以我们可以直接查看源代码

5、从代码看,在delete之后,还使用指针访问了成员函数和成员变量。从调试来看,在delete之后,可以调用成员函数,只有当访问成员变量时,程序会中断(对于VS2008来说,也可能不会,偶现)

	delete pBase;
	pBase->UnInit();
	pBase->nLignt = 111;
	std::cout << pBase->nValue << std::endl;

因此delete一个指针时,指针指向的内存区域并不会被清空,因为这样会占用CPU周期,此时它是一个危险的指针,会造成一些未定义的现象(或者是个野指针,若打印成员变量的值可能是个随机值)。根据测试情况,有可能发生崩溃有可能不会,因此就会出现,这些代码可能长时间运行不崩溃的情况,接着可能在某个时间点或者修改了某些逻辑后发生了崩溃,这种问题在大型的项目中是比较难发现的,有时候也不好复现。因此在代码编写的时候我们就要养成良好的习惯,在delete指针之后,最好是将其置为NULL,保证我们所使用的是一个有效的指针,而不是会造成不可预见错误的野指针。
使用new或malloc分配内存时,C ++会在内存中找到一些未使用的空间,将其标记为“已分配”(以确保该空间不会在释放前再次被使用),并为我们提供其地址。当使用delete操作指针, C ++会将其指向的内存区域标记为“未分配”,并可能将其交给任何要求它的人。这时候这块空间就可以被其他人进行操作:写入或者读取。因此再次操作类对象或类成员就会出错,因为内存中的内容以及大小都可能发生了变化。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值