999999999 内存泄漏问题

yazi321 2005-08-24 04:16:16
class CQueue
{
public:
struct ELEMENT
{
int m_nThreadNum,m_nRequestNum;
};
typedef ELEMENT* PELEMENT;

private:
PELEMENT m_pElements;
int m_nMaxElements;
HANDLE m_h[2];
HANDLE &m_hmtxQ;
HANDLE &m_hsenNumElements;

public:
CQueue(int nMaxElements);
~CQueue();

BOOL Append(ELEMENT &pElement, DWORD dwTimeout);
BOOL Remove(ELEMENT &pElement, DWORD dwTimeout);
};


CQueue::CQueue(int nMaxElements):m_hmtxQ(m_h[0]),m_hsenNumElements(m_h[1])
{
m_pElements = (PELEMENT)HeapAlloc(GetProcessHeap(),0,sizeof(ELEMENT)*nMaxElements);
m_nMaxElements = nMaxElements;
m_hmtxQ = CreateMutex(NULL,FALSE,NULL);
m_hsenNumElements = CreateSemaphore(NULL,0,nMaxElements,NULL);
}

CQueue::~CQueue()
{

CloseHandle(m_hsenNumElements);
CloseHandle(m_hmtxQ);
HeapFree(GetProcessHeap(),0,m_pElements);
}

BOOL CQueue::Append(ELEMENT &pElement, DWORD dwTimeout)
{
BOOL fOK = FALSE;
DWORD dw = WaitForSingleObject(m_hmtxQ,dwTimeout);
if(dw == WAIT_OBJECT_0)
{
LONG IPrevCount;
fOK = ReleaseSemaphore(m_hsenNumElements,1,&IPrevCount);
if(fOK)
{
m_pElements[IPrevCount].m_nThreadNum = pElement.m_nThreadNum;
m_pElements[IPrevCount].m_nRequestNum = pElement.m_nRequestNum;
}
else
{
SetLastError(ERROR_DATABASE_FULL);//溢出
}
ReleaseMutex(m_hmtxQ);
}
else
{
SetLastError(ERROR_TIMEOUT);
}
return(fOK);
}

BOOL CQueue::Remove(ELEMENT &pElement, DWORD dwTimeout)
{
BOOL fOK = ( WaitForMultipleObjects(2,m_h,TRUE,dwTimeout ) == WAIT_OBJECT_0 );

if(fOK)
{
pElement = m_pElements[0];
MoveMemory(&m_pElements[0],&m_pElements[1],sizeof(ELEMENT)*(m_nMaxElements-1));//移出一个
ReleaseMutex(m_hmtxQ);
}
else
{
SetLastError(ERROR_TIMEOUT);
}
return(fOK);
}

class CDlgqueue : public CDialog
{
// Construction
public:
CDlgqueue(CWnd* pParent = NULL); // standard constructor

HANDLE m_handle;
// Dialog Data
//{{AFX_DATA(CDlgqueue)
enum { IDD = IDD_DIALOG2 };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA


// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgqueue)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:

// Generated message map functions
//{{AFX_MSG(CDlgqueue)
virtual BOOL OnInitDialog();
afx_msg void OnButton2();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
static DWORD WINAPI ClientThread(LPVOID pvPara);
static DWORD WINAPI ServerThread(LPVOID pvPara);
static DWORD WINAPI ButtonThread(LPVOID pvPara);
};




#include "stdafx.h"
#include "msg.h"
#include "Dlgqueue.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

volatile BOOL g_fshutdown = TRUE;
HWND g_hwnd;
CQueue g_q(10);
HANDLE g_hThreads[MAXIMUM_WAIT_OBJECTS];
int g_nNumThreads;


/////////////////////////////////////////////////////////////////////////////
// CDlgqueue dialog


CDlgqueue::CDlgqueue(CWnd* pParent /*=NULL*/)
: CDialog(CDlgqueue::IDD, pParent)
{
//{{AFX_DATA_INIT(CDlgqueue)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
g_nNumThreads= 0;
}


void CDlgqueue::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgqueue)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgqueue, CDialog)
//{{AFX_MSG_MAP(CDlgqueue)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgqueue message handlers

BOOL CDlgqueue::OnInitDialog()
{
CDialog::OnInitDialog();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

DWORD WINAPI CDlgqueue::ClientThread(LPVOID pvPara)
{
int nThreadNum = PtrToUlong(pvPara);
HWND hwndLB = ::GetDlgItem(g_hwnd,IDC_LISTCLIENT);

for(int nRequestNum = 1; g_fshutdown; nRequestNum++)
{
try
{
TCHAR sz[1024];
CQueue::ELEMENT e = {nThreadNum,nRequestNum};
if(g_q.Append(e,200))
{
wsprintf(sz,TEXT("Sending %d:%d"),nThreadNum,nRequestNum);
}
else
{
wsprintf(sz,TEXT("Sending %d:%d(%s)"),nThreadNum,nRequestNum,
(GetLastError() == ERROR_TIMEOUT) ? TEXT("timeout"):TEXT("full") );
}
ListBox_SetCurSel(hwndLB,ListBox_AddString(hwndLB,sz) );
Sleep(2500);
}
catch (...)
{
Sleep(1000);
}

}
return(0);
}

DWORD WINAPI CDlgqueue::ServerThread(LPVOID pvPara)
{
int nThreadNum = PtrToUlong(pvPara);

HWND hwndLB = ::GetDlgItem(g_hwnd,IDC_LISTSERVER);

while (g_fshutdown)
{
try
{
TCHAR sz[1024];
CQueue::ELEMENT e;
if(g_q.Remove(e,5000))
{
wsprintf(sz,TEXT("%d:Processing %d:%d"),nThreadNum,e.m_nThreadNum,e.m_nRequestNum);
Sleep(2000*e.m_nThreadNum);
}
else
{
wsprintf(sz,TEXT("%d:(timeout)"),nThreadNum);
}
ListBox_SetCurSel(hwndLB,ListBox_AddString(hwndLB,sz) );
}
catch (...)
{
Sleep(1000);
}
}
return(0);
}

void CDlgqueue::OnButton2()
{
g_hwnd = this->m_hWnd;
InterlockedExchange((LONG*)&g_fshutdown,(LONG)TRUE);
for(int x=0;x<4;x++)
{
g_hThreads[g_nNumThreads++]=::CreateThread(NULL,0,ClientThread,(PVOID)(INT_PTR)x,0,NULL);
}
for(x=0;x<2;x++)
{
g_hThreads[g_nNumThreads++]=::CreateThread(NULL,0,ServerThread,(PVOID)(INT_PTR)x,0,NULL);
}

m_handle = ::CreateThread(NULL,0,ButtonThread,this,0,NULL);
/*
WaitForMultipleObjects(g_nNumThreads,g_hThreads,TRUE,INFINITE);
while (g_nNumThreads--)
{
CloseHandle(g_hThreads[g_nNumThreads]);
}*/

}

DWORD WINAPI CDlgqueue::ButtonThread(LPVOID pvPara)
{
WaitForMultipleObjects(g_nNumThreads,g_hThreads,TRUE,INFINITE);
while (g_nNumThreads--)
{
CloseHandle(g_hThreads[g_nNumThreads]);
}
return(0);
}
...全文
135 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
Darkay_Lee 2005-08-24
  • 打赏
  • 举报
回复
.^_^。反驳楼上
void foo()
{
new ...
}
void bar()
{
delete ...
}
foo();foo();foo();bar();
mituzhishi 2005-08-24
  • 打赏
  • 举报
回复
内存泄露的原因在于:new 的次数大于 delete 的次数。

64,637

社区成员

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

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