2011-03-21 83 views
-3

我得到了以下代码,其中最后一条语句我尝试删除指向动态创建的内存的指针。删除ptr解决了访问冲突异常写入0

但只要我得到的指令访问冲突异常引发话说:0000005:在 SERVER.EXE在0x0094c91f

未处理的异常访问 冲突读取位置00000000。

但是当我通过它一步与调试器包含在它的有效数据的有效地址...我不知道我在做什么致命的错误在这里...

任何建议?

void CServer::HandleAcceptRequest(ACCEPT_REQUEST* pRequest) 
{ 
    //Add the new connection socket to the connection handler 
    m_pConnectionHandler->AddConnection(pRequest->m_NewConnection); 
    //Associate the new connections´ socket handle with the IOCP 
    if(!m_pCompletionPort->AssociateHandle((HANDLE)pRequest->m_NewConnection, 0)) 
    { 
     MessageBox(NULL, "Could not associate a socket handle with the completion port", "", MB_ICONERROR | MB_OK); 
     DebugBreak(); 
    } 


    //Create a new COMM_REQUEST and initialize a Recv-Request 
    COMM_REQUEST* pCommRequest = new COMM_REQUEST; 
    memset(pCommRequest, 0, sizeof(COMM_REQUEST)); 
    pCommRequest->Socket = pRequest->m_NewConnection; 
    pCommRequest->m_RequestType = BASIC_REQUEST::RECV; 

    WSABUF* buf = new WSABUF; 
    buf->buf = pCommRequest->cBuf; 
    buf->len = Inc::COMMUNICATION_BUFFER_SIZE; 
    DWORD dwFlags = 0; 
    if(WSARecv(pCommRequest->Socket, buf, 1, NULL, &dwFlags, pCommRequest, NULL)) 
    { 
     DWORD dwRet = WSAGetLastError(); 
     if(dwRet != WSA_IO_PENDING) 
     { 
      MessageBox(NULL, "WSARecv() failed", "", MB_ICONERROR | MB_OK); 
      DebugBreak(); 
     } 
    }; 

    //Delete the old ACCEPT_REQUEST structure 
    delete pRequest; 
} 

编辑:我做了分配在另一个函数的内存在主线程

bool CConnectionHandler::AcceptNewConnection(SOCKET ListenSocket, unsigned nCount) 
{ 
    DWORD dwBytesReceived = 0; 
    ACCEPT_REQUEST* pOverlapped = nullptr; 

    for(unsigned n = 0; n < nCount; n++) 
    { 
     dwBytesReceived = 0; 
     pOverlapped = new ACCEPT_REQUEST; 
     memset(pOverlapped, 0, sizeof(ACCEPT_REQUEST)); 
     pOverlapped->m_RequestType = ACCEPT_REQUEST::ACCEPT; 

     //add the ListenSocket to the request 
     pOverlapped->m_ListenSocket = ListenSocket; 
     //invalidate the new connection socket 
     pOverlapped->m_NewConnection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
     if(pOverlapped->m_NewConnection == INVALID_SOCKET) 
     { 
      delete pOverlapped; 
      return false; 
     } 

     // call 'AcceptEx' 
     if(m_lpfnAcceptEx(pOverlapped->m_ListenSocket, pOverlapped->m_NewConnection, pOverlapped->cOutputBuffer, 0, sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, &dwBytesReceived, pOverlapped) == FALSE) 
     { 
      DWORD dwRet = WSAGetLastError(); 
      if(dwRet == ERROR_IO_PENDING) 
       continue; 
      else 
       return false; 
     } 
    } 

    return true; 
}; 

EDIT2:线程代码做给参数的功能...

unsigned int WINAPI ServerThreadFunc(void* pvArgs) 
{ 
    CServer* pServer = (CServer*)pvArgs;  // pointer to the server object 
    DWORD dwBytes = 0; 
    ULONG_PTR ulKey; 
    OVERLAPPED* pOverlapped = nullptr; 
    bool bLooping = true; 

    while(bLooping) 
    { 
     //TODO: Add code (ServerThreadFunc) 
     if(!pServer->m_pCompletionPort->GetCompletionStatus(&dwBytes, &ulKey, &pOverlapped, INFINITE)) 
     { 
      //TODO: Set some error variable or flag an error event to notify the main thread 
      DebugBreak(); 
     } 

     //check type of request 
     switch(((BASIC_REQUEST*)pOverlapped)->m_RequestType) 
     { 
     case BASIC_REQUEST::ACCEPT: 
      { 
       // TODO: Handle AcceptEx-request 
       pServer->HandleAcceptRequest(static_cast<ACCEPT_REQUEST*>(pOverlapped)); 
+1

你在哪里分配了这个内存? – sth 2011-03-21 23:13:10

+1

pRequest来自哪里?它只是在代码中显示为不受欢迎的客人! :) – ralphtheninja 2011-03-21 23:14:20

+0

确实现在增加了两个功能 – Incubbus 2011-03-21 23:16:37

回答

1

对不起,没有办法真正从你提供的零件中找出任何东西。

然而,在第三个代码你有这样的电话

pServer->HandleAcceptRequest(static_cast<ACCEPT_REQUEST*>(pOverlapped)); 

这个调用将通过调用它delete破坏*pOverlapped对象。 (请记住,在HandleAcceptRequest的最后,您的值为delete pRequest,其中pRequestHandleAcceptRequest的参数)。

这将使pOverlapped一个悬挂指针指向死记忆。我没有看到代码中的任何地方你会重新初始化该悬挂指针或将其设置为空。

如果您不重新初始化它,那么在周期中下一次访问*pOverlapped将访问死区(可能看起来“有效”),并且下一次尝试delete它很可能会再次崩溃。如果下一个delete尝试再次是HandleAcceptRequest末尾的那个,那么该行为可能与您最初描述的完全相同。

+0

为什么这个叫“删除”呢? – Incubbus 2011-03-21 23:28:57

+2

@Incubbus:因为你自己在'HandleAcceptRequest'结尾调用'delete'。记得你所问的非常“删除”? – AnT 2011-03-21 23:30:50

+1

嗨!我是一个网络服务器! http://xkcd.com/869/;) – ralphtheninja 2011-03-21 23:35:33

0
OVERLAPPED* pOverlapped = nullptr; 
.. 
pServer->m_pCompletionPort->GetCompletionStatus(&dwBytes, &ulKey, &pOverlapped, INFINITE); 

好的。看来你正在删除错误的指针。您在HandleAcceptRequest()内部删除的内容不再是指向OVERLAPPED的指针,因为指针已从OVERLAPPED *转换为ACCEPT_REQUEST *。

GetCompletionStatus()是你自己的?