线程里怎么释放GlobalAlloc开辟的内存(几个疑问)
一个代理服务器的测试代码,以下一个工作线程,问题是内存释放不完整,程序工作一段时间会越来越大,时间长了估计把内存全吃掉。由于本人C++新手,故有下面红字疑问,希望高人帮忙解答,大家一定帮忙看看,在此先谢过:) 代理太多就不全粘,如果要看全部联系我,我QQ传给你,QQ232588929
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE hCompletionPort = (HANDLE) CompletionPortID;
DWORD dwBytesTransferred = 0;
SOCKET hSocket;
LPWSAOVERLAPPEDEX lpOvlpEx;
int nErr;
while (1)
{
BOOL r = GetQueuedCompletionStatus(hCompletionPort,&dwBytesTransferred,(LPDWORD)&hSocket,(LPWSAOVERLAPPED *) &lpOvlpEx,INFINITE );
....................忽略
//可疑1:pConnOvlEx在下面开辟了一个内存空间,在程序中怎么释放
WSAOVERLAPPEDEX * pConnOvlEx = (WSAOVERLAPPEDEX *) GlobalAlloc(GPTR,sizeof(WSAOVERLAPPEDEX));
lpOvlpEx->pPair = pConnOvlEx;//互相
pConnOvlEx->pPair = lpOvlpEx;//指定
lpOvlpEx->hSocketPair = hConnect;
pConnOvlEx->hSocketPair = lpOvlpEx->hSocket;
pConnOvlEx->hSocket = hConnect;
pConnOvlEx->WSABuf.buf = pConnOvlEx->Buffer;
pConnOvlEx->WSABuf.len = DATA_BUFSIZE;
pConnOvlEx->pProxy3 = pConnOvlEx->pProxy3;
CreateIoCompletionPort((HANDLE)hConnect,hCompletionPort,(DWORD)hConnect,0);
DWORD dwRecvBytes = 0,dwFlags = 0;
ZeroMemory(pConnOvlEx,sizeof(WSAOVERLAPPED));
pConnOvlEx->WSABuf.len = DATA_BUFSIZE;
if ( WSARecv(hConnect,&pConnOvlEx->WSABuf,1,&dwRecvBytes,&dwFlags,(LPWSAOVERLAPPED)pConnOvlEx,NULL) == SOCKET_ERROR)
{
if ( WSAGetLastError() != WSA_IO_PENDING)
{
SafeClose(lpOvlpEx); //可疑2:SafeClose是释放内存函数--请看本文最后面定义,能否释放以上pConnOvlEx指针空间,即上面GlobalAlloc的空间,如果不能,那应该怎么释放pConnOvlEx用的内存
continue;
}
}
}
//转发
DWORD dwReadBytes = 0,dwFlags = 0;
ZeroMemory(lpOvlpEx,sizeof(WSAOVERLAPPED));
lpOvlpEx->WSABuf.len = dwBytesTransferred;
if ( WSASend(lpOvlpEx->hSocketPair,&lpOvlpEx->WSABuf,1,&dwReadBytes,dwFlags,(LPWSAOVERLAPPED)lpOvlpEx,NULL) == SOCKET_ERROR)
{
if ( WSAGetLastError() != WSA_IO_PENDING)
{
SafeClose(lpOvlpEx);
continue;
}
}
}
else if (hSocket == lpOvlpEx->hSocketPair)
{//数据发送完,转入接收状态
DWORD dwRecvBytes = 0,dwFlags = 0;
lpOvlpEx->WSABuf.len = DATA_BUFSIZE;
ZeroMemory(lpOvlpEx,sizeof(WSAOVERLAPPED));
if ( WSARecv(lpOvlpEx->hSocket,&lpOvlpEx->WSABuf,1,&dwRecvBytes,&dwFlags,(LPWSAOVERLAPPED)lpOvlpEx,NULL) == SOCKET_ERROR)
{
if ( WSAGetLastError() != WSA_IO_PENDING)
{
//printf("%d recv err = %d\n",lpOvlpEx->hSocket,WSAGetLastError());
SafeClose(lpOvlpEx);
continue;
}
}
}
}
return 0;
}
}
void SafeClose(LPWSAOVERLAPPEDEX lpOvlpEx)
{
if ( lpOvlpEx->pPair != NULL )
{
SOCKET hPair = lpOvlpEx->hSocketPair;
lpOvlpEx->pPair->hSocketPair = INVALID_SOCKET - 1; //告诉伴侣我关了
lpOvlpEx->pPair->pPair = NULL;//告诉伴侣内存自己放了
closesocket(lpOvlpEx->hSocket); //close自己
GlobalFree(lpOvlpEx);//释放自己
GlobalFree(lpOvlpEx->pPair); //可疑3:我自己加的,pConnOvlEx不就是lpOvlpEx->pPair么,那我释放它,结果使用程序,测试连接上去就出错退出了。 shutdown(hPair,SD_BOTH);//把伴侣置位shutdown
}
else
{
closesocket(lpOvlpEx->hSocket); //close自己
GlobalFree(lpOvlpEx);//释放自己
}
}