1.按一个按钮,dlg.domodle();弹出对话框,在弹出的对话框上按确定(cdialge::onok)返回,内存并未被释放,为什么?(只看到内存增加,未看到内存减少!)
2.再按上面的按钮,内存又增加了,怎么释放!!!!!!!!!!1
3.现在我的程序运行内存增加的厉害,大家都说boundchecks好用,但我装了,虽然显示程序实时运行的情况,但并不能指示我到底是哪些语句导致了内存泄露啊,!!请教大家调试的经验!!!!!
2.再按上面的按钮,内存又增加了,怎么释放!!!!!!!!!!1
3.现在我的程序运行内存增加的厉害,大家都说boundchecks好用,但我装了,虽然显示程序实时运行的情况,但并不能指示我到底是哪些语句导致了内存泄露啊,!!请教大家调试的经验!!!!!
如果是类的,一般会提示哪里NEW 了类,变量不提示,找到它们在对话框的wm_destroy中删除或者在析构函数中删除
cdialog dlg;
dlg.domodle();弹出对话框;那怎么才能收回内存啊!!!
看看是否是GDI对象未释放, COM对象没有释放, 是否使用了不正确的数据库操作等等
没有详细的信息难以知道究竟是什么原因导致这种情况
不是这句的问题 不是你的 cdialog 里有内存泄漏 如OnInitDialog 函数里 new了内存没回收
class CTempSetup : public CDialog
{
// Construction
public:
CTempSetup(CWnd* pParent = NULL); // standard constructor// Dialog Data
//{{AFX_DATA(CTempSetup)
enum { IDD = IDD_DLG_TEMPSET };
CShadeButtonST m_Cancel;
CShadeButtonST m_Ok;
CEdit m_rel_normalTemp;
CEdit m_rel_GapTemp;
CEdit m_rel_envirTemp;
CEdit m_abs_minAlarmTemp;
CEdit m_abs_normalTemp;
CTabCtrl m_tab;
//}}AFX_DATA
CBrush m_brush;
CBitmap m_bmp_bk;
CFont m_font;
CFont m_fontTitle;// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTempSetup)
public:
virtual BOOL DestroyWindow();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL// Implementation
protected: // Generated message map functions
//{{AFX_MSG(CTempSetup)
virtual BOOL OnInitDialog();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnClickTab4(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnChangeEditAbsnomaltemp();
afx_msg void OnChangeEditAlarmMintemp();
afx_msg void OnChangeEditEnvirTemp();
afx_msg void OnChangeEditGap();
afx_msg void OnChangeEditRenomaltemp();
afx_msg void OnButtonOk();
afx_msg void OnButtonCancel();
afx_msg void OnClose();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_TEMPSETUP_H以上是头文件!!!!!!!!// TempSetup.cpp : implementation file
//#include "stdafx.h"
#include "try.h"
#include "TempSetup.h"
#include "tryView.h"
#include "mainfrm.h"
#include "Graph.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CTempSetup dialog
CTempSetup::CTempSetup(CWnd* pParent /*=NULL*/)
: CDialog(CTempSetup::IDD, pParent)
{
//{{AFX_DATA_INIT(CTempSetup)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_bmp_bk.LoadBitmap(IDB_BKBMP);
m_brush.CreatePatternBrush(&m_bmp_bk);
m_fontTitle.CreatePointFont(300,"楷体_GB2312");
m_font.CreatePointFont(120,"黑体");
}
void CTempSetup::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTempSetup)
DDX_Control(pDX, IDC_BUTTON_OK, m_Cancel);
DDX_Control(pDX, IDC_BUTTON_CANCEL, m_Ok);
DDX_Control(pDX, IDC_EDIT_RENOMALTEMP, m_rel_normalTemp);
DDX_Control(pDX, IDC_EDIT_GAP, m_rel_GapTemp);
DDX_Control(pDX, IDC_EDIT_ENVIR_TEMP, m_rel_envirTemp);
DDX_Control(pDX, IDC_EDIT_ALARM_MINTEMP, m_abs_minAlarmTemp);
DDX_Control(pDX, IDC_EDIT_ABSNOMALTEMP, m_abs_normalTemp);
DDX_Control(pDX, IDC_TAB4, m_tab);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTempSetup, CDialog)
//{{AFX_MSG_MAP(CTempSetup)
ON_WM_CTLCOLOR()
ON_NOTIFY(NM_CLICK, IDC_TAB4, OnClickTab4)
ON_EN_CHANGE(IDC_EDIT_ABSNOMALTEMP, OnChangeEditAbsnomaltemp)
ON_EN_CHANGE(IDC_EDIT_ALARM_MINTEMP, OnChangeEditAlarmMintemp)
ON_EN_CHANGE(IDC_EDIT_ENVIR_TEMP, OnChangeEditEnvirTemp)
ON_EN_CHANGE(IDC_EDIT_GAP, OnChangeEditGap)
ON_EN_CHANGE(IDC_EDIT_RENOMALTEMP, OnChangeEditRenomaltemp)
ON_BN_CLICKED(IDC_BUTTON_OK, OnButtonOk)
ON_BN_CLICKED(IDC_BUTTON_CANCEL, OnButtonCancel)
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CTempSetup message handlersBOOL CTempSetup::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
MoveWindow(342,405,650,310,TRUE);
CTryView *p=(CTryView*)((CMainFrame*)AfxGetMainWnd())->GetActiveView();
int i;
static char num;
num='A';
char *pNum=#
for ( i=0;i< (p->m_ptrArray.GetSize());i++)
{
m_tab.InsertItem(i,pNum);
num++;
}
m_Ok.SetIcon(IDI_ICON1,IDI_ICON2);
m_Cancel.SetIcon(IDI_ICON3,IDI_ICON4);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}HBRUSH CTempSetup::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
if (nCtlColor==CTLCOLOR_STATIC)
{
pDC->SetBkMode(TRANSPARENT);
pDC->SelectObject(&m_font);
pDC->SetTextColor(RGB(100,100,230));
}
if (pWnd->GetDlgCtrlID()==IDC_TAB2)
{
pDC->SelectObject(&m_brush);
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(100,100,230));
}
// TODO: Return a different brush if the default is not desired
return m_brush;
}void CTempSetup::OnClickTab4(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
int sel = m_tab.GetCurSel(); //获取当前监测点
CTryView *p=(CTryView*)((CMainFrame*)AfxGetMainWnd())->GetActiveView();
CDetectArea * ptr = //ptr指向当前监测点的数据结构
(CDetectArea *)p->m_ptrArray.GetAt(sel); CString str;
float temp;
/*************************************/
temp =ptr->m_abs_minAlarmTemp;
str.Format("%3.3f",temp);
m_abs_minAlarmTemp.SetWindowText(str);
/*************************************/
temp =ptr->m_abs_normalTemp;
str.Format("%2.2f",temp);
m_abs_normalTemp.SetWindowText(str);/*************************************/
temp =ptr->m_rel_envirTemp;
str.Format("%2.2f",temp);
m_rel_envirTemp.SetWindowText(str);
/*************************************/
temp =ptr->m_rel_GapTemp;
str.Format("%2.2f",temp);
m_rel_GapTemp.SetWindowText(str);
/*************************************/
temp =ptr->m_rel_normalTemp;
str.Format("%2.2f",temp);
m_rel_normalTemp.SetWindowText(str);
/*************************************/
*pResult = 0;}void CTempSetup::OnChangeEditAbsnomaltemp()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
int sel = m_tab.GetCurSel(); //获取当前监测点
CTryView *p=(CTryView*)((CMainFrame*)AfxGetMainWnd())->GetActiveView();
CDetectArea * ptr = //ptr指向当前监测点的数据结构
(CDetectArea *)p->m_ptrArray.GetAt(sel); CString str;
m_abs_normalTemp.GetWindowText(str);
ptr->m_abs_normalTemp=atof(str);
}void CTempSetup::OnChangeEditAlarmMintemp()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
int sel = m_tab.GetCurSel(); //获取当前监测点
CTryView *p=(CTryView*)((CMainFrame*)AfxGetMainWnd())->GetActiveView();
CDetectArea * ptr = //ptr指向当前监测点的数据结构
(CDetectArea *)p->m_ptrArray.GetAt(sel); CString str;
m_abs_minAlarmTemp.GetWindowText(str);
ptr->m_abs_minAlarmTemp=atof(str);
}void CTempSetup::OnChangeEditEnvirTemp()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
int sel = m_tab.GetCurSel(); //获取当前监测点
CTryView *p=(CTryView*)((CMainFrame*)AfxGetMainWnd())->GetActiveView();
CDetectArea * ptr = //ptr指向当前监测点的数据结构
(CDetectArea *)p->m_ptrArray.GetAt(sel); CString str;
m_rel_envirTemp.GetWindowText(str);
ptr->m_rel_envirTemp=atof(str);
}void CTempSetup::OnChangeEditGap()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
int sel = m_tab.GetCurSel(); //获取当前监测点
CTryView *p=(CTryView*)((CMainFrame*)AfxGetMainWnd())->GetActiveView();
CDetectArea * ptr = //ptr指向当前监测点的数据结构
(CDetectArea *)p->m_ptrArray.GetAt(sel); CString str;
m_rel_GapTemp.GetWindowText(str);
ptr->m_rel_GapTemp=atof(str);
}void CTempSetup::OnChangeEditRenomaltemp()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
int sel = m_tab.GetCurSel(); //获取当前监测点
CTryView *p=(CTryView*)((CMainFrame*)AfxGetMainWnd())->GetActiveView();
CDetectArea * ptr = //ptr指向当前监测点的数据结构
(CDetectArea *)p->m_ptrArray.GetAt(sel); CString str;
m_rel_normalTemp.GetWindowText(str);
ptr->m_rel_normalTemp=atof(str);
}void CTempSetup::OnButtonOk()
{
// TODO: Add your control notification handler code here
CDialog::OnOK();
}void CTempSetup::OnButtonCancel()
{
// TODO: Add your control notification handler code here
CDialog::OnCancel();
}void CTempSetup::OnClose()
{
// TODO: Add your message handler code here and/or call default CDialog::OnClose();
}BOOL CTempSetup::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
m_brush.DeleteObject();
m_font.DeleteObject();
m_bmp_bk.DeleteObject();
return CDialog::DestroyWindow();
}
以上是.cpp的内容,该释放的我都释放了啊
m_font.DeleteObject();
m_bmp_bk.DeleteObject(); msdn:
An application should not call DeleteObject on a CGdiObject object that is currently selected into a device context. 当一个正被选入设备上下文的gdiobject的应用不应该使用deleteobject来删除它,你必须先选入原始 的GDI对象,才能删除新对象改进是在头文件加入比方:CFont *m_pOldFont;//在构造函数里初始为NULL;
在CTempSetup::OnCtlColor
里面m_pOldFont = pDC->SelectObject(&m_font);在BOOL CTempSetup::DestroyWindow() {
if(m_pOldFont != NULL)
{ pDC->SelectObject(&m_font);
m_font.DeleteObject();
}
...
}
{ pDC->SelectObject(m_pOldFont);
m_font.DeleteObject();
}
这个类有很多问题(不是指功能上),比如内存泄漏,句柄没有释放等
我只能一句一句的道程序中去找出对应的没有释放的对象吗?
有没有什么简单点的方法可以知道到底是哪些对象没有被释放啊!!!!!
CTempSetup::OnCtlColor 这个函数在对话框重绘时就会调用,也就是说在CTempSetup类的生命周期里,这个函数可能将被多次调用,
当第一次调用时,pDC->SelectObject(&m_font);这个函数返回一个old字体指针,新的字体已经选入了设备环境,当第二次调用时
pDC->SelectObject(&m_font)这个函数返回的应该是,你已经选入到设备环境中新的字体,到这时,原始的字体已经丢失了, m_pOldFont
和m_font已经代表了同一种字体,当最后又将与当前设备环境中字体重新选入到设备环境,pDC->SelectObject(m_pOldFont); 也就是说
原始的字体并没有选入到设备环境,所以,我认为你的字体资源并不会被释放. 最后建议CTempSetup::OnCtlColor 函数里的m_pOldFont = pDC->SelectObject(&m_font);剪贴到CTempSetup::OnInitDialog()函数里,其余不变
HBRUSH CTempSetup::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here
if (nCtlColor==CTLCOLOR_STATIC)
{
pDC->SetBkMode(TRANSPARENT);
pDC->SelectObject(&m_font);
pDC->SetTextColor(RGB(100,100,230));
}
if (pWnd->GetDlgCtrlID()==IDC_TAB2)
{
pDC->SelectObject(&m_brush);
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(100,100,230));
}
// TODO: Return a different brush if the default is not desired
return m_brush;
}
SelectObject后要在结束后选回原来的
CBursh *pOldBr = pDC->SelectObject(&m_brush);
……
// 用完后
pDC->SelectObject(pOldBr);
老外编的就一定值得信赖吗???
源码的cshadeButtonst在功能上是没有问题的,但是有资源的泄漏,
长期跑,会挂掉的
提示一下,m_fontTitle没释放。
还有DestroyWindow()中的内容直接放入OnOk()和OnCancel()中不行吗?