用完成端口做一个通讯程序,在主线程中定时发送WsaSend命令,
在完成端口线程中接收数据WsaRecv。
问题是:
在发送WsaSend命令前,要分配LPPER_IO_DATA内存,现在是不知道在什么
地方释放分配的内存。
void CSHBiao::SendCmd()
{
    char elbCmd = 0xe3;
    char biaoCmd = 0xee;

    charARRAY cmd; 
    long nCmdLen;
    int nRet;
    CCommand *pCmd = NULL;
    pCmd = BuildCmd(cmd, &elbCmd, 1, &biaoCmd, 1);
    if(!pCmd) 
    {
        nRet = -1;
    }

    DWORD dwByteSend;
    LPPER_IO_DATA lpPerIoData = (LPPER_IO_DATA) new char[sizeof(PER_IO_DATA)];
    ZeroMemory(lpPerIoData, sizeof(PER_IO_DATA));
    nCmdLen = cmd.size();
    cmd.push_back('\0'); //[nCmdLen] = '\0';
    memcpy(lpPerIoData->Buffer, &cmd[0], nCmdLen);
    lpPerIoData->WSABuf.buf = lpPerIoData->Buffer;
    lpPerIoData->WSABuf.len = nCmdLen;
    lpPerIoData->nSendBytes = 0;
    lpPerIoData->nTotalBytes = nCmdLen;
    lpPerIoData->hSocket = m_socket;
    nRet = WSASend(m_socket, &lpPerIoData->WSABuf, 1, &dwByteSend, 0, 
                   &(lpPerIoData->Overlapped), NULL);
    CTime stTime;
    stTime = CTime::GetCurrentTime();
    if(nRet == 0)
    {
        //把命令加入列表
        AddCmdToList(pCmd);
    }
    else
    {
if(WSAGetLastError() == WSA_IO_PENDING)
{
int i=0;
}
else
{
}
    }
    delete lpPerIoData;   -----这一行出错,把lpPerIoData释放,
                              -----命令就没法发送。
                              -----不释放,命令发送成功,但内存泄漏
}

解决方案 »

  1.   

    发送完毕释放,具体应该看m_socket的异步模式
      

  2.   

    直接定义PER_IO_DATA类型对象不就可以了么。为何要用指针并new分配空间
      

  3.   

    现在在完成端口的线程中的WsaSend发送成功时
    delete lpPerIoData后没有内存泄漏,不知道
    这样正确不正确?
      

  4.   

    原则上是谁分配的,谁释放.
    malloc--->free
    new---delete
    new[]-->delet[]
      

  5.   

    现在在完成端口的线程中的WsaSend发送成功时
    delete lpPerIoData后没有内存泄漏,不知道
    这样正确不正确?如果没有发送成功呢??怎么处理
      

  6.   

    nRet = WSASend(m_socket, &lpPerIoData->WSABuf, 1, &dwByteSend, 0, 
                       &(lpPerIoData->Overlapped), NULL);传递的都是地址,当你释放lpPerIoData时这些地址都释放了,当然会报错。有一个办法就是将lpPerIoData设置为全局变量或设置为参数的形式。
      

  7.   

    to nuaawenlin:
    我知道会错误,才问你们如何解决?我想知道解决的方法。谢谢各位大侠。
      

  8.   

    一般应该在GetQueuedCompletionStatus函数返回后,接着处理相关的单句柄内存和单io内存的释放问题,不然你在别处删除,完成端口肯定会出错