内存泄露与内存管理讨论,分数不多,问题尖锐,谢谢!

VCILOVE 2009-11-27 11:20:03
测试环境如下:
1. WINXP,VC60,BounderChecker
2. 生成一个WIN32 APP工程,名为Test。
用BounderChecker发现有内存泄露,但是我们能从代码分析不是内存泄露。

Test.CPP文件内容如下:

// Test.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"
#include "MyClass.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text

// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;

// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TEST, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TEST);

char *p = NULL;
SetMemory(p);
delete [] p;
p = NULL;

char *t = NULL;
t = new char [10240000];


// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
delete [] t;
return msg.wParam;
}



//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TEST);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_TEST;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

return RegisterClassEx(&wcex);
}

//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}

//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
...全文
103 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuchuncai 2009-11-27
  • 打赏
  • 举报
回复
void SetMemory(char *p)
{
p = new char[102400000];
return;
}

这个写得有严重问题。

BYTE* SetMemory()
{
BYTE* p = new char[102400000];
return p;
}
「已注销」 2009-11-27
  • 打赏
  • 举报
回复
void SetMemory(char *p)
{
p = new char[102400000];
return;
}
我对你这个函数及其调用的语句比较感兴趣Yeah...
VCILOVE 2009-11-27
  • 打赏
  • 举报
回复
大家回复的太快了,呵呵
我还没有写完,我的问题在#3楼,呵呵
谢谢!
VCILOVE 2009-11-27
  • 打赏
  • 举报
回复
续上:
另外一个CPP文件内容如下:
#include "stdafx.h"

void SetMemory(char *p)
{
p = new char[102400000];
return;
}
头文件内容如下:
void SetMemory(char *p);

分配100MB内存,然后释放,
用WINDOWS 任务管理器来看,分配到了100MB内存,关闭程序后,100MB内存被释放。
现在的问题是:
1. 使用BounderChecker提示内存泄露。
2. 但是Delete了P后,在不退出的程序界面的情况下,内存并没有被释放。
3. 又重新分配了内存T,发现在增加100MB(P的内存)的情况下,又增加了10MB,并没有复用原有的内存。
4. 如果把DELETE T的代码放到分配T的内存代码的下一句,发现内存被立即释放了(通过任务管理器)。
5. 如果注释掉Delete T的代码,关闭程序后,内存也被释放。

现在就是高不清楚了,是不是有内存泄露,一个程序分配的内存到底是怎么管理的。
为什么不Delete也可以被释放。
请高手解答一下,谢谢!
codelast.com 2009-11-27
  • 打赏
  • 举报
回复
BoundsCheck俺曾经装过,但是无法使用,唉
ctolee 2009-11-27
  • 打赏
  • 举报
回复
你的问题是?

BoundsCheck本来就有误报的情况


还有下次放代码的时候,带点格式。。
VCILOVE 2009-11-27
  • 打赏
  • 举报
回复
清楚了,谢谢!
ahao 2009-11-27
  • 打赏
  • 举报
回复
基本的传值传址你没搞清楚

void SetMemory(char *p)
{
p = new char[102400000];
return;
}

这么写立马泄漏,要返回p,改成

void SetMemory(char*& p)
{
p = new char[102400000];
return;
}
VCILOVE 2009-11-27
  • 打赏
  • 举报
回复
看了啊,严重有问题,到底是什么问题呢,请指明一下,谢谢!
ahao 2009-11-27
  • 打赏
  • 举报
回复
上面不是都回答了么?你不看的???
VCILOVE 2009-11-27
  • 打赏
  • 举报
回复
我想知道的是,程序New出来的内存操作系统是如何管理的,
因为我发现:
1. 程序未退出,释放New出来的内存,操作系统立即得到。
2. 程序未推出,释放New出来的内存,操作系统没有得到???
3. 程序退出后,不管是不是释放了,都被操作系统回收了

哪个大大知道???

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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