我在用网上一个完成端口例子实现自己的应用时,有两个地方经boundschecker检查有内存泄漏,但是不知道怎么处理,希望高手指点一下,谢谢谢谢!!
1.第一处
if(! bError && bEnterRead) 
{
// issue a read request 
OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IORead);//这里有内存泄漏
ULONG ulFlags = MSG_PARTIAL; UINT nRetVal = WSARecv(lpClientContext->m_Socket, 
&lpClientContext->m_wsaInBuffer,
1,
&dwIoSize, 
&ulFlags,
&pOverlap->m_ol, 
NULL); if ( nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) 
{
pThis->RemoveStaleClient( lpClientContext, FALSE );
}
}
2.第二处
void CIOCPServer::Send(const CString& strClient, CString strData)
{
ClientContext* pContext = FindClient(strClient);
if (pContext == NULL)
return;

int nBufLen = strData.GetLength(); // 4 byte header [Size of Entire Packet]
pContext->m_WriteBuffer.Write((PBYTE) &nBufLen, sizeof(nBufLen)); pContext->m_WriteBuffer.Write((PBYTE) strData.GetBuffer(nBufLen), nBufLen);

// Wait for Data Ready signal to become available
WaitForSingleObject(pContext->m_hWriteComplete, INFINITE); // Prepare Packet
int nSize = pContext->m_WriteBuffer.GetBufferLen();
pContext->m_wsaOutBuffer.buf = (CHAR*) new BYTE[nSize];//这里有内存泄漏
pContext->m_wsaOutBuffer.len = nSize; OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IOWrite);
PostQueuedCompletionStatus(m_hCompletionPort, 0, (DWORD) pContext, &pOverlap->m_ol); pContext->m_nMsgOut++;
}

解决方案 »

  1.   

    没有delete 肯定泄露了啊当你申请的空间不使用了,就delete
    delete pOverlap; 
    delete [](pContext- >m_wsaOutBuffer.buf);
      

  2.   

    OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IORead);//这里有内存泄漏
    pContext- >m_wsaOutBuffer.buf = (CHAR*) new BYTE[nSize];//这里有内存泄漏 
    OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IOWrite); //应该还有这个地方。
    主要原因是:
    1)使用new分配的是堆内存,堆内存在c++语法中的规定是:谁分配谁释放,也就是说用户自己分配了内存,那么
    用户必须要手动释放这些内存,也就是必须调用delete,然后再赋值为NULL(这个的主要作用是防止出现野指针)
    delete pOverlap;
    pOverlap = NULL;delete []pContext- >m_wsaOutBuffer.buf;
    pContext- >m_wsaOutBuffer.buf = NULL;
    这里又有一个新的问题: 就是delete []和delete又有什么区别?其实就是一个是数组版的delete,一个是单的
    delete.
    例如: int * i = new int;
    delete i;
    i = NULL;
    必须这样使用,才不会出现内存泄露和野指针.
    2) 则是栈内存,也就是没有调用new,在函数内存分配的内存,如int i = 0;其实这样需要分配内存,但这个内存不
    需要自己释放,有编译器来释放.
      

  3.   

    LZ必须知道内存还有: 
    1) delete的背后做哪些工作
    2) 有malloc,也有new,这些的区别又是什么?
    3)new,new[],delete,delete[]的含义,及作用是什么,这些LZ也必须清楚?
    4) 栈内存和堆内存的区别又是什么?
    5) delete函数后,如果没有赋值为NULL的后果是什么?
    这个5个问题LZ必须清楚,才能更好的使用指针.
      

  4.   

    在指针即将实效前delete之。另,被传递的指针一般由接受者释放,视需要而定。
      

  5.   

    感谢楼上诸位,有一点没说明白,我知道delete,也正是采用了shanhqk的方法,如下:
    delete pOverlap; 
    pOverlap = NULL; delete []pContext-  >m_wsaOutBuffer.buf; 
    pContext-  >m_wsaOutBuffer.buf = NULL; 这样做才报错,原代码中没有这两句,所以才不会处理,不知道大家看过这个例子没有,codeproject上面的,文章名字是Developing a Truly Scalable Winsock Server using IO Completion Ports,例子直接就有泄漏。
      

  6.   

    最终定位到了这里
    _ASSERTE(_CrtIsValidHeapPointer(pUserData));
      

  7.   

    更改一下:
    struct ClientContext
    {
        SOCKET m_Socket; // Store buffers
    CBuffer m_ReadBuffer;
    CBuffer m_WriteBuffer; // Input Elements for Winsock
    WSABUF m_wsaInBuffer;
    BYTE m_byInBuffer[8192];     // Output elements for Winsock
    WSABUF m_wsaOutBuffer;
    HANDLE m_hWriteComplete; // Message counts... purely for example purposes
    LONG m_nMsgIn;
    LONG m_nMsgOut; ClientContext* m_pWriteContext;
    ClientContext* m_pReadContext;
    ClientContext()
    {}
    ~ClientContext()
    {
    if (NULL != m_wsaOutBuffer.buf)
    {
      delete m_wsaOutBuffer.buf;
      m_wsaOutBuffer.buf = NULL;
    }
    }};
      

  8.   


    我这个是砖贴,楼主等玉吧。:)new出来的东西
    用delete肯定是没错的。只不过是过程中有什么地方做的不对,应该跟踪一下错误信息,到底是什么错误。
    贴上来看,