2011-03-21 85 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()是你自己的?