写了一个用于网络通信的软件,在运行时发现了少量的内存泄露,不知道是什么原因。程序里没有直接使用过new malloc之类的语句,但使用了多个线程。
不知道什么时候会出现内存泄露,线程中使用了窗体要释放吗?
另有什么免费的便于使用的内存泄露查找工具?

解决方案 »

  1.   

    绝大多数的线程只执行一次就退出了,收发消息有两个线程,心跳包一个线程,不过没有用过动态分配内存的,奇怪的是程序的内存泄露大概没20秒一次掉4k大小的内存,可是我的线程没有sleep(20000);的,现在不知道要怎么入手查找
      

  2.   

    DWORD WINAPI ServerWorkThread(LPVOID lpParam)
    {
    ......
    while(1)
    {
    WaitForSingleObject(manager->hMutexProc,INFINITE);
    cout<<"PRS:In Process\n"; HRESULT hres;
        hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
        
        hres =  CoInitializeSecurity(
            NULL, 
            -1,                          // COM authentication
            NULL,                        // Authentication services
            NULL,                        // Reserved
            RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
            RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
            NULL,                        // Authentication info
            EOAC_NONE,                   // Additional capabilities 
            NULL                         // Reserved
            );
                          
        IWbemLocator *pLoc = NULL;    hres = CoCreateInstance(
            CLSID_WbemLocator,             
            0, 
            CLSCTX_INPROC_SERVER, 
            IID_IWbemLocator, (LPVOID *) &pLoc);
     
        IWbemServices *pSvc = NULL;

        hres = pLoc->ConnectServer(
             _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
             NULL,                    // User name. NULL = current user
             NULL,                    // User password. NULL = current
             0,                       // Locale. NULL indicates current
             NULL,                    // Security flags.
             0,                       // Authority (e.g. Kerberos)
             0,                       // Context object 
             &pSvc                    // pointer to IWbemServices proxy
             );
        
        hres = CoSetProxyBlanket(
           pSvc,                        // Indicates the proxy to set
           RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
           RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
           NULL,                        // Server principal name 
           RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
           RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
           NULL,                        // client identity
           EOAC_NONE                    // proxy capabilities 
        );    IEnumWbemClassObject* pEnumerator = NULL;
        hres = pSvc->ExecQuery(
            bstr_t("WQL"), 
            bstr_t("SELECT * FROM Win32_Process"),
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
            NULL,
            &pEnumerator);
        
      IWbemClassObject *pclsObj;
        ULONG uReturn = 0;
        CString strOld;    int count=0;
    CString ProcessId;
    CString ProcessName;
    while (pEnumerator)
    {
    count++;
    HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
     &pclsObj, &uReturn); if(0 == uReturn)
    {
     break;
    } VARIANT vtProp;
    VariantInit(&vtProp); // Get the value of the Name property
    hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
    ProcessName+=vtProp.bstrVal; hr = pclsObj->Get(L"ProcessId", 0, &vtProp, 0, 0);
    char p[8];
    itoa(vtProp.scode,p,10);
    ProcessId+=p;
            
    ProcessName+="|";
    ProcessId+="|";
    VariantClear(&vtProp);
    }
    //cout<<"PRS:have got\n"<<strProcess<<endl;
    //manager->BufWrite.Push(strProcess);
    SOCKADDR_IN addr;
    char chHostName[256];
    struct hostent *Host = NULL;
    gethostname(chHostName, 256);
    Host = gethostbyname(chHostName);
    if (Host)
    CopyMemory(&addr.sin_addr, Host->h_addr_list[0], Host->h_length); My_msg m_msg;
    m_msg.IP=manager->DesAddr;
    m_msg.IP.sin_port=5001;
    m_msg.str="[906]{";
    m_msg.str+=strIpAddress;
    m_msg.str+="}{";
    m_msg.str+=ProcessName;
    m_msg.str+="}"; pSvc->Release();
        pLoc->Release();
        pEnumerator->Release();
        pclsObj->Release();
        CoUninitialize(); manager->BufWrite.Push(m_msg); std::cout<<"PRS:Sleeping\n"; 
    ReleaseMutex(manager->hMutexWriteBuf); Sleep(5000);
    }
    }
      

  3.   

    第二个不会退出的线程
    while(1)
    {
    if (theApp.bIsExit)
    break; WaitForSingleObject(manager->hMutexReadBuf,INFINITE);//是否有其他线程访问“读缓冲区”
    //如果没有其他线程访问数据区,则本线程开始访问缓冲区的内容
    if(manager->BufRead.getLength())
    {//如果缓冲区有数据则进行下面的处理
    My_msg m_msg;
    m_msg.str="";
                    m_msg=manager->BufRead.Pop();//得到缓冲区的数据
    //下面得到缓冲区数据的处理编号,数据的类型[xxx]{}{}{}......,其中xxx为处理编号后面花括号中的内容是与数据处理相关的内容
    /*
    CString str;
    str=m_msg.str.GetAt(1);
    str+=m_msg.str.GetAt(2);
    str+=m_msg.str.GetAt(3);
    cout <<"\nRUN:\n";
    */
    //Message和其他的CPrcXXX类构成了一个“Observer”模式,
    //下面的内容是调用Messager类的Update函数,
    //通知所有处理函数察看处理编号看看是否是自己要处理的内容
    // m_msg.str=str;
    m_ProcMSG->setDoc(manager->pDocument);
    m_ProcMSG->setMsg(m_msg);
    m_ProcMSG->Update();
    cout<<"\n------------------------\n";
    //将处理完的数据存入"写缓冲区"
    /*
    WaitForSingleObject(manager->hMutexWriteBuf,INFINITE);//察看“写缓冲区”是否有其他线程操作
    manager->BufWrite.Push(m_ProcMSG->getMsg());//将处理完的数据存入“写缓冲区”
    ReleaseMutex(manager->hMutexWriteBuf);
    */
    }
    ReleaseMutex(manager->hMutexReadBuf);
    Sleep(10);
    }
      

  4.   

    第三个线程,负责数据写出
    while(1)
    {
    if (theApp.bIsExit)
    break;
    using namespace std;
    WaitForSingleObject(manager->hMutexWriteBuf,INFINITE);
    My_msg strPop;
    int i=manager->BufWrite.getLength();
    if (i)
    {
    strPop=manager->BufWrite.Pop();

    kk.buf=(LPTSTR)(LPCTSTR)(strPop.str);
    kk.len=(strPop.str).GetLength(); addr1=strPop.IP;//获取客户机ip
    addr1.sin_port=5000;         WSASendTo (sock, /* socket */ 
             &kk,/* output buffer structure */ 
    1, /* buffer count */ 
    &LengthSend, /* number of bytes sent */
    0, /* flags */ 
    (struct sockaddr*)&addr1, /* destination address */ 
    sizeof(struct sockaddr), /* size of addr structure */ 
    NULL, /* overlapped structure */ 
    NULL); /* overlapped callback function */ 
    cout<<"SND:Sending........\n"<<kk.buf<<endl;
    }
    ReleaseMutex(manager->hMutexWriteBuf);
    // ReleaseMutex(manager->hMutexProc);
    //sleep in send
    Sleep(500);
    }
      

  5.   

    莫非是IWbemServices 的原因?
      

  6.   

    哪里有免费下载的公司用不了edonkey和sheraza
      

  7.   

    问题找到了,居然是是因为DC没释放出的问题,但是出错的地方是在MFC提供的类里面,不知道要怎么才能找到我的程序出错的具体地方
      

  8.   

    http://www.cnitblog.com/wangk/archive/2005/12/14/5369.html
      

  9.   

    那个CoUninitialize确实存在问题,但不是内存泄露,不知道问题出在什么地方。