首先说下我IOCP的实现下面的发送包时的代码
-------------------------------------------------------------------------
PER_IO_CONTEXT* overlappedEx=new PER_IO_CONTEXT
overlappedEx->IOOperation= WRITE; 
overlappedEx->wsabuf.buf= (char *)malloc( nLen ); 
if( NULL == overlappedEx->wsabuf.buf ) 

delete overlappedEx; 
return -1; 
} if(WSASend(m_socket,&(overlappedEx->wsabuf), 0x01, &dwBytes, 0x00, &(overlappedEx->Overlapped), NULL ) == SOCKET_ERROR) 
-------------------------------------------------------------------------
下面是完成端口通知时的处理代码
-------------------------------------------------------------------------
 while (m_bIsRun)
 {
  result = GetQueuedCompletionStatus(m_hCompletionPort,&iosize,&key,&overlapped,INFINITE);
  if ( 0 == key ) 
  {
   break;
  }
  if( NULL != overlappedEx )
  {
   if ( WRITE == overlappedEx->IOOperation )
   {   
    delete overlappedEx;
    continue;
   }
}……
}
-------------------------------------------------------------------------之后在     delete overlappedEx; 前面用 OutPutDebugString 打印了调试信息, 发现在 
 delete overlappedEx; 执行后WSASend 里面还会访问到  overlappedEx结构下面的  Overlapped,结果就在 WSASend 出现内存不能读的错误!overlappedEx 的结构体定义如下:struct PER_IO_CONTEXT
{
 WSAOVERLAPPED    Overlapped;
 WSABUF                      wsabuf;
 IO_OPERATION         IOOperation;
};

解决方案 »

  1.   

    为什么要 delete overlappedEx;  ?只在断开连接时才 delete overlappedEx;
    平时一直用开始new的那个
      

  2.   

    overlappedEx结构是不能删的,必须等WSASend把数据发送结束才可以释放空间,windows的所有Overlapped都有这个要求
      

  3.   

    楼上的, “overlappedEx结构是不能删的,必须等WSASend把数据发送结束才可以释放空间,windows的所有Overlapped都有这个要求” msdn 哪里有这样的说明?1. 如果在 WSASend 发送完才 delete overlappedEx; 这时有可能  GetQueuedCompletionStatus 还在处理中
    2. 如果在 GetQueuedCompletionStatus 那边 delete 这时有可能 WSASend 那边也在处理中。
      

  4.   

    不知道你用的是什么样的思路:
    我的思路是写一个postSend函数,试将缓存的数据发送出去..
    在onSend中判断是否发送完毕,没有再投递一个postSend
    之前的Overlapped在onSend执行完后马上被删除(原因是
    在postSend会重新分配内存空间Overlapped)
      

  5.   

    PER_IO_CONTEXT* overlappedEx=new PER_IO_CONTEXT 
    overlappedEx->IOOperation= WRITE; 
    overlappedEx->wsabuf.buf= (char *)malloc( nLen ); delete overlappedEx; 之前
    先把wsabuf.buf的内存释放掉,然后再delete。