标准c写的windows程序因为使用内存过量导致程序崩溃,问题在哪儿?

zhangze 2003-10-29 07:21:25
/*以下程序使用标准c编写,运行一段时间之后会变得不响应。从内存使用上来看,程序占用的内存越来越多,没办法释放,那位有解决的办法,回复本贴或者QQ:23033206都可以,急用,多谢!*/
#include <windows.h>
#include <time.h>
#include "resource.h"
#define SCREENWIDTH 128
#define SCREENHEIGHT 128
HINSTANCE instance;
HBITMAP bmpstart;
int visualflag,delay;
void DrawAll(HDC dc);
void MainMenu();
void DrawBmp(HDC dc, int x, int y, int width, int height,HBITMAP bmp, int sx, int sy, int transparent);

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR pCmdLine,int iCmdShow)
{
MSG msg;
WNDCLASSEX wndproc;
HWND hWnd;
instance=hInstance;
wndproc.cbSize=sizeof(WNDCLASSEX);
wndproc.lpfnWndProc=(WNDPROC)WndProc;
wndproc.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_OWNDC;
wndproc.cbClsExtra=0;
wndproc.cbWndExtra=0;
wndproc.hInstance=hInstance;
wndproc.hIcon=NULL;
wndproc.hCursor=LoadCursor(NULL,IDC_ARROW);
wndproc.hbrBackground=(HBRUSH)(0);
wndproc.lpszMenuName=NULL;
wndproc.lpszClassName="abc";
wndproc.hIconSm=NULL;
RegisterClassEx(&wndproc);
hWnd=CreateWindow("abc","abc",WS_OVERLAPPEDWINDOW|WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,SCREENWIDTH,SCREENHEIGHT+26,NULL,NULL,hInstance,NULL);
if(!hWnd)
return 0;
bmpstart=LoadBitmap(instance,MAKEINTRESOURCE(IDB_start));
SetTimer (hWnd, 1, 30, NULL);
while(GetMessage(&msg,NULL,0,0))
{

DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND wnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
HDC dc,buf=0;
RECT rect;
PAINTSTRUCT paint;
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_TIMER:

MainMenu();

rect.left = rect.top = 0;
rect.right = SCREENWIDTH;
rect.bottom = SCREENHEIGHT;
InvalidateRect (wnd, & rect, 0);
break;
case WM_PAINT:
dc=BeginPaint(wnd,&paint);
GetClientRect (wnd, & rect);
if (!buf)
{
buf = CreateCompatibleDC(dc);
SelectObject (buf,
CreateCompatibleBitmap(dc, SCREENWIDTH, SCREENHEIGHT));
}
DrawAll (buf);
BitBlt(dc, 0, 0, SCREENWIDTH, SCREENHEIGHT, buf, 0, 0, SRCCOPY);
EndPaint(wnd,&paint);
DeleteObject(buf);
break;
case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_SYSCHAR:
case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_RBUTTONDBLCLK:
case WM_MOUSEMOVE:
break;
default:
return DefWindowProc(wnd,msg,wParam,lParam);
}
return 0;
}
void DrawAll(HDC dc)
{ if(visualflag)
{
DrawBmp(dc,15,80,93,20,bmpstart,0,0,0);
}
}

void MainMenu()
{
delay--;
if(delay<=0)
{
visualflag=visualflag==0?1:0;
delay=10;
}
}
void DrawBmp(HDC dc, int x, int y, int width, int height,
HBITMAP bmp, int sx, int sy, int transparent)
{
HDC buf = CreateCompatibleDC (dc);
SelectObject (buf, bmp);
if (transparent)
TransparentBlt ( dc,x,y,width,height,buf,sx,sy,width,height,RGB(255,255,255));
else
StretchBlt (dc,x, y,width,height,buf, sy, sy, width, height,SRCCOPY);
DeleteObject (buf);
}
...全文
43 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
fierygnu 2003-10-30
  • 打赏
  • 举报
回复
所有的对象不用的时候都需要销毁,否则就会占用系统空间(注意不一定是应用的空间)。而dc里的对象有些是系统的,多进程公用的,因此你不能作主销毁,必须选回去,由DeleteObject(dc)去做判断。
zhangze 2003-10-30
  • 打赏
  • 举报
回复
原来如此,非常感谢fierygnu(va_list)。看来我得系统研究一下windows的一些东西了~~~~~
我想了想,虽然明白为什么会溢出,但有些地方还不是很清楚。能给我解释一下为什么会出现这种现象?
fierygnu 2003-10-30
  • 打赏
  • 举报
回复
SelectObject(buf,iBitmap);
DeleteObject(iBitmap); //不对,这里不用删
下面:
BitBlt(dc, 0, 0, SCREENWIDTH, SCREENHEIGHT, buf, 0, 0, SRCCOPY);
SelectObject (buf, hObj); //这个返回的obj应该删,可以用DeleteObject(SelectObject(buf, hObj));
DeleteObject(buf);
zhangze 2003-10-30
  • 打赏
  • 举报
回复
/*问题依然存在,这是我修改后的源代码,你看看还有那些地方需要修改*/
#include <windows.h>
#include <time.h>
#include "resource.h"
#define SCREENWIDTH 128
#define SCREENHEIGHT 128
HINSTANCE instance;
HBITMAP bmpstart;
int visualflag,delay;
void DrawAll(HDC dc);
void MainMenu();
void DrawBmp(HDC dc, int x, int y, int width, int height,HBITMAP bmp, int sx, int sy, int transparent);

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR pCmdLine,int iCmdShow)
{
MSG msg;
WNDCLASSEX wndproc;
HWND hWnd;
instance=hInstance;
wndproc.cbSize=sizeof(WNDCLASSEX);
wndproc.lpfnWndProc=(WNDPROC)WndProc;
wndproc.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_OWNDC;
wndproc.cbClsExtra=0;
wndproc.cbWndExtra=0;
wndproc.hInstance=hInstance;
wndproc.hIcon=NULL;
wndproc.hCursor=LoadCursor(NULL,IDC_ARROW);
wndproc.hbrBackground=(HBRUSH)(0);
wndproc.lpszMenuName=NULL;
wndproc.lpszClassName="abc";
wndproc.hIconSm=NULL;
RegisterClassEx(&wndproc);
hWnd=CreateWindow("abc","abc",WS_OVERLAPPEDWINDOW|WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,SCREENWIDTH,SCREENHEIGHT+26,NULL,NULL,hInstance,NULL);
if(!hWnd)
return 0;
bmpstart=LoadBitmap(instance,MAKEINTRESOURCE(IDB_start));
SetTimer (hWnd, 1, 30, NULL);
while(GetMessage(&msg,NULL,0,0))
{
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND wnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
HDC dc,buf=0;
RECT rect;
HGDIOBJ hObj;
PAINTSTRUCT paint;
rect.left = rect.top = 0;
rect.right = SCREENWIDTH;
rect.bottom = SCREENHEIGHT;
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_TIMER:

MainMenu();
InvalidateRect (wnd, & rect, 0);
break;
case WM_PAINT:
dc=BeginPaint(wnd,&paint);
GetClientRect (wnd, & rect);
if (!buf)
{
buf = CreateCompatibleDC(dc);
hObj =SelectObject (buf,
CreateCompatibleBitmap(dc, SCREENWIDTH, SCREENHEIGHT));
}
DrawAll (buf);
BitBlt(dc, 0, 0, SCREENWIDTH, SCREENHEIGHT, buf, 0, 0, SRCCOPY);
SelectObject (buf, hObj);
DeleteObject(buf);
EndPaint(wnd,&paint);

/* DeleteObject(buf);*/

break;
case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_SYSCHAR:
case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_RBUTTONDBLCLK:
case WM_MOUSEMOVE:
break;
default:
return DefWindowProc(wnd,msg,wParam,lParam);
}
return 0;
}
void DrawAll(HDC dc)
{ if(visualflag)
{
DrawBmp(dc,15,80,93,20,bmpstart,0,0,0);
}
}

void MainMenu()
{
delay--;
if(delay<=0)
{
visualflag=visualflag==0?1:0;
delay=10;
}
}
void DrawBmp(HDC dc, int x, int y, int width, int height,
HBITMAP bmp, int sx, int sy, int transparent)
{
HBITMAP iBitmap;
HDC buf = CreateCompatibleDC (dc);
iBitmap=SelectObject (buf, bmp);
if (transparent)
TransparentBlt ( dc,x,y,width,height,buf,sx,sy,width,height,RGB(255,255,255));
else
StretchBlt (dc,x, y,width,height,buf, sy, sy, width, height,SRCCOPY);
SelectObject(buf,iBitmap);
DeleteObject(iBitmap);
DeleteObject (buf);
/* ReleaseDC(instance,buf);*/

}
fierygnu 2003-10-30
  • 打赏
  • 举报
回复
象这样:
HGDIOBJ hObj = SelectObject (buf, CreateCompatibleBitmap(dc, SCREENWIDTH, SCREENHEIGHT));
...
hBitmap = SelectObject (buf, hObj);
DeleteObject(hBitmap);
DeleteObject(buf);
zhangze 2003-10-30
  • 打赏
  • 举报
回复
你所说的第二点我做了,但第一点怎么实现
fierygnu 2003-10-30
  • 打赏
  • 举报
回复
1、selectobject返回的object在不使用dc后要选回去;
2、CreateCompatibleBitmap出来的东西没有deleteobject。
zhangze 2003-10-30
  • 打赏
  • 举报
回复
我也认为是内存泄漏问题。但是程序要运行好久才会出现。应该如何补救?
蟑螂工作室 2003-10-30
  • 打赏
  • 举报
回复
如果是程序在使用过程中,不断把内存消耗掉,应该存在内存泄漏问题,但看你提供的代码好像没有new|malloc,建议你在VC--debug状态下,调试F5,若有内存泄漏在output窗口中会有提示
北极猩猩 2003-10-30
  • 打赏
  • 举报
回复
肯定是存在内存泄漏问题,使用VC应该可以查出来导致泄露的地点
zhangze 2003-10-30
  • 打赏
  • 举报
回复
和那句无关系,即使存在那一句也会发生同样的结果。我使用vc编译器
daizh 2003-10-29
  • 打赏
  • 举报
回复
SetTimer (hWnd, 1, 30, NULL);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);//少了这句语句,添上试试。
DispatchMessage(&msg);
}
return 0;
showming 2003-10-29
  • 打赏
  • 举报
回复
关注!

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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