关于程序内存泄露问题?

virtualzege 2012-10-18 11:51:38
程序可以运行,奇怪的是只进入主菜单界面后,就退出程序,并不会提示内存泄露;

但是当程序进入主菜单界面后,再进入实际游戏场景后,退出程序后就会提示内存泄露问题。

该问题的产生是我在添加DirectInput组件后产生的。

但是初始化输入设备是在进入主菜单界面之前做的,而非进入实际游戏场景之前做的。

并且如果我只进入主菜单界面,就算有按键行为,退出时依旧没有内存问题;

但是如果进入了实际游戏场景,就算没有按键行为,退出时依旧会提示内存问题;

而且每次进入实际游戏场景后再退出时,编译器都会给出如下信息:(相同的)

Direct3D9: (ERROR) :Memory still allocated! Alloc count = 3057
Direct3D9: (ERROR) :Current Process (pid) = 00000fb4(这个每次不一定相同)
Direct3D9: (ERROR) :Memory Address: 028e07fc lAllocID=1 dwSize=00004bc4, ReturnAddr=6480d5ea (pid=00000fb4)
Direct3D9: (ERROR) :Memory Address: 028e53f4 lAllocID=2 dwSize=00000350, ReturnAddr=648102fa (pid=00000fb4)
Direct3D9: (ERROR) :Memory Address: 028e577c lAllocID=3 dwSize=00000ef0, ReturnAddr=64816401 (pid=00000fb4)
Direct3D9: (ERROR) :Memory Address: 028f0064 lAllocID=5 dwSize=00006300, ReturnAddr=6481e508 (pid=00000fb4)
Direct3D9: (ERROR) :Memory Address: 028f639c lAllocID=6 dwSize=00001584, ReturnAddr=6480ec04 (pid=00000fb4)
Direct3D9: (ERROR) :Memory Address: 028f7954 lAllocID=7 dwSize=00000004, ReturnAddr=6480ed27 (pid=00000fb4)
Direct3D9: (ERROR) :Memory Address: 028e66a4 lAllocID=9 dwSize=000012fc, ReturnAddr=64803cab (pid=00000fb4)
.
.
.
.
.
Direct3D9: (ERROR) :Memory Address: 029dd4fc lAllocID=106 dwSize=0000002c, ReturnAddr=6480d5ea (pid=00000fb4)
Direct3D9: (ERROR) :Memory Address: 029dd55c lAllocID=107 dwSize=00000030, ReturnAddr=6480d5ea (pid=00000fb4)
Direct3D9: (ERROR) :Memory Address: 029dd5c4 lAllocID=108 dwSize=0000517c, ReturnAddr=6480d5ea (pid=00000fb4)
Direct3D9: (ERROR) :Memory Address: 048b0064 lAllocID=109 dwSize=00020020, ReturnAddr=6480d5ea (pid=00000fb4)
Direct3D9: (ERROR) :Total Memory Unfreed From Current Process = 3967089 bytes

请问如何解决这个问题?该如何调试?十分感谢了~~
...全文
342 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
virtualzege 2012-10-24
  • 打赏
  • 举报
回复
自个儿找找~~
gzliaojian 2012-10-19
  • 打赏
  • 举报
回复
windbg看看heap吧!
virtualzege 2012-10-19
  • 打赏
  • 举报
回复
感谢各位朋友的建议及意见!

正在深度自检中~~~
fujialin2011 2012-10-19
  • 打赏
  • 举报
回复
要是代码比较复杂的话,使用c/c++内存检测工具Leak Detector 来查吧!可以辅助你找到内存泄漏的地方
赵4老师 2012-10-19
  • 打赏
  • 举报
回复
C:\samples\VC98\sdk\Graphics\DirectX\diex3\DIEX3.CPP节选:
...
/****************************************************************************
*
* DIInit
*
* Initialize the DirectInput variables.
*
* This entails the following four functions:
*
* DirectInputCreate
* IDirectInput::CreateDevice
* IDirectInputDevice::SetDataFormat
* IDirectInputDevice::SetCooperativeLevel
*
****************************************************************************/

BOOL
DIInit(
HWND hwnd
)
{
HRESULT hr;

/*
* Register with the DirectInput subsystem and get a pointer
* to a IDirectInput interface we can use.
*
* Parameters:
*
* g_hinst
*
* Instance handle to our application or DLL.
*
* DIRECTINPUT_VERSION
*
* The version of DirectInput we were designed for.
* We take the value from the <dinput.h> header file.
*
* &g_pdi
*
* Receives pointer to the IDirectInput interface
* that was created.
*
* NULL
*
* We do not use OLE aggregation, so this parameter
* must be NULL.
*
*/
hr = DirectInputCreate(g_hinst, DIRECTINPUT_VERSION, &g_pdi, NULL);

if (FAILED(hr)) {
Complain(hwnd, hr, "DirectInputCreate");
return FALSE;
}

/*
* Obtain an interface to the system keyboard device.
*
* Parameters:
*
* GUID_SysKeyboard
*
* The instance GUID for the device we wish to access.
* GUID_SysKeyboard is a predefined instance GUID that
* always refers to the system keyboard device.
*
* &g_pKeyboard
*
* Receives pointer to the IDirectInputDevice interface
* that was created.
*
* NULL
*
* We do not use OLE aggregation, so this parameter
* must be NULL.
*
*/
hr = g_pdi->CreateDevice(GUID_SysKeyboard, &g_pKeyboard, NULL);

if (FAILED(hr)) {
Complain(hwnd, hr, "CreateDevice");
return FALSE;
}

/*
* Set the data format to "keyboard format".
*
* A data format specifies which controls on a device we
* are interested in, and how they should be reported.
*
* This tells DirectInput that we will be passing an array
* of 256 bytes to IDirectInputDevice::GetDeviceState.
*
* Parameters:
*
* c_dfDIKeyboard
*
* Predefined data format which describes
* an array of 256 bytes, one per scancode.
*/
hr = g_pKeyboard->SetDataFormat(&c_dfDIKeyboard);

if (FAILED(hr)) {
Complain(hwnd, hr, "SetDataFormat");
return FALSE;
}


/*
* Set the cooperativity level to let DirectInput know how
* this device should interact with the system and with other
* DirectInput applications.
*
* Parameters:
*
* DISCL_NONEXCLUSIVE
*
* Retrieve keyboard data when acquired, not interfering
* with any other applications which are reading keyboard
* data.
*
* DISCL_FOREGROUND
*
* If the user switches away from our application,
* automatically release the keyboard back to the system.
*
*/
hr = g_pKeyboard->SetCooperativeLevel(hwnd,
DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);

if (FAILED(hr)) {
Complain(hwnd, hr, "SetCooperativeLevel");
return FALSE;
}

return TRUE;

}

/****************************************************************************
*
* DITerm
*
* Terminate our usage of DirectInput.
*
****************************************************************************/

void
DITerm(void)
{

/*
* Destroy any lingering IDirectInputDevice object.
*/
if (g_pKeyboard) {

/*
* Cleanliness is next to godliness. Unacquire the device
* one last time just in case we got really confused and tried
* to exit while the device is still acquired.
*/
g_pKeyboard->Unacquire();

g_pKeyboard->Release();
g_pKeyboard = NULL;
}

/*
* Destroy any lingering IDirectInput object.
*/
if (g_pdi) {
g_pdi->Release();
g_pdi = NULL;
}

}
...
赵4老师 2012-10-19
  • 打赏
  • 举报
回复
检查是否资源泄漏的办法之一:
在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象
让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!
赵4老师 2012-10-18
  • 打赏
  • 举报
回复
参考:
MSDN98\SAMPLES\VC98\SDK\GRAPHICS\DIRECTX\DIEX3\*.*
MSDN98\SAMPLES\VC98\SDK\GRAPHICS\DIRECTX\DIEX4\*.*

ftp.bartol.udel.edu/evenson/TRANSFER/DN60AENU1/SAMPLES/VC98/SDK/GRAPHICS/DIRECTX/DIEX3/
漫步者、 2012-10-18
  • 打赏
  • 举报
回复
内存分配失败,把内存分配大小改一下试试
virtualzege 2012-10-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

不能断点之后进行单步调试么?

或者看看调用堆栈?
[/Quote]

摁,我就是用的断点单步调试的。退出程序时,释放程序加载的资源都正常,然后~~

执行UnregisterClassW(WINDOW_CLASS,g_hInstance);

然后 return 0;

然后转到crtexe.c文件中的这个地方:

if ( !managedapp )

exit(mainret);
就是做 exit(mainret)函数时,编译器开始提示内存分配错误~(见1楼的具体问题描述),

随后程序凄凉的退出~~

求解~?

十分感谢了!
jixingzhong 2012-10-18
  • 打赏
  • 举报
回复
不能断点之后进行单步调试么?

或者看看调用堆栈?
virtualzege 2012-10-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

记得用过后释放内存了没。。?使用new 创建后,要使用delete释放了。。
如果没有使用,则使包含指针的内存由于作用域和对象生命周期的原因而被释放,在自由存储空间上动态分配的变量或结构将继续存在。实际上,将会无法访问自由存储空间中的结构,因为指向这些内存的指针无效。这将导致内存泄露
[/Quote]
我也仔细看了,在程序退出前貌似都释放了的~~。哎!
  • 打赏
  • 举报
回复
记得用过后释放内存了没。。?使用new 创建后,要使用delete释放了。。
如果没有使用,则使包含指针的内存由于作用域和对象生命周期的原因而被释放,在自由存储空间上动态分配的变量或结构将继续存在。实际上,将会无法访问自由存储空间中的结构,因为指向这些内存的指针无效。这将导致内存泄露

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧