繁体   English   中英

C ++ / CLI方法中的内存泄漏

[英]Memory Leak in C++/CLI method

我在代码中找到了此调用的内存泄漏:

BitmapSource snapshot = VideoPlayer.GetCurrentImage();

VideoPlayer是一个C ++ / CLI库,此方法的代码为:

WriteableBitmap^ VideoPlayback::GetCurrentImage()
{
    BITMAPINFOHEADER bih;
    BYTE *pDib = 0;
    DWORD cbDib = 0;
    LONGLONG timeStamp = 0;

    memset(&bih, 0, sizeof(bih));
    bih.biSize = sizeof(BITMAPINFOHEADER);
    HRESULT hr = m_pPlayer->GetCurrentImage(&bih, &pDib, &cbDib, &timeStamp);

    if (FAILED(hr)) throw gcnew MFException(hr);

    WriteableBitmap^ res = ToWritableBitmap(bih, pDib, cbDib, true);

    CoTaskMemFree(pDib);

    return res;
}

和ToWriteableBitmap:

WriteableBitmap^ VideoPlayback::ToWritableBitmap(const BITMAPINFOHEADER& bih, BYTE* pDib, DWORD cbDib, bool bInvert)
{
    WriteableBitmap^ res;
    AtlTrace(_T("image size: %d x %d, bitCount: %d, bufferSize: %d\n"), bih.biWidth, bih.biHeight, bih.biBitCount, cbDib);

    switch (bih.biBitCount)
    {
        //could there be any other format!?
    case 24:
        //AtlTrace(_T("24bit image not supported!"));
        res = gcnew WriteableBitmap(bih.biWidth, bih.biHeight, 72.0, 72.0, System::Windows::Media::PixelFormats::Bgr24, nullptr);
        break;
    case 32:
        res = gcnew WriteableBitmap(bih.biWidth, bih.biHeight, 72.0, 72.0, System::Windows::Media::PixelFormats::Bgr32, nullptr);
        break;
    }
    if (res!=nullptr)
    {
        int stride = res->BackBufferStride;
        res->Lock();

        if (bInvert)
        {
            BYTE* pBuf = (BYTE*)res->BackBuffer.ToPointer();

            BYTE* pDest = pBuf + (bih.biHeight - 1) * stride;
            BYTE* pSrc = pDib;
            //the image is inverted
            for (int y = 0; y < bih.biHeight; y++)
            {
                memcpy(pDest, pSrc, stride);
                pSrc+=stride;
                pDest-=stride;
            }
        }
        else
        {
            BYTE* pDest = (BYTE*)res->BackBuffer.ToPointer();
            memcpy(pDest, pDib, bih.biSizeImage);
        }

        res->AddDirtyRect(System::Windows::Int32Rect(0, 0, bih.biWidth, bih.biHeight));
        res->Unlock();
    }   
    return res;
}

当我在windbg中运行!threads时,多次调用此方法会导致某些对象被“固定”,并且DeadThread计数很高。 在这些死线程上运行!gcroot ,我得到:

DOMAIN(00000000036553A0):HANDLE(固定):5417c8:根目录:0000000022423378(System.Object [])->
00000000125f0c08(System.Collections.ArrayList)->
0000000012d96950(System.Object [])->
0000000012e44460(System.Windows.Media.MediaContext)->
0000000012e43e80(System.Windows.Threading.Dispatcher)->
0000000012e30480(System.Threading.Thread)

其中System.Object[]的地址始终相同。

调用后如何正确清理线程才能完成? 还是C ++代码有问题?

问题是我在后台线程中创建BitmapSource。 一旦我使用Dispatcher.Invoke调用此方法,线程泄漏就消失了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM