C ++在Windows上数百次重复后屏幕捕获失败:内存泄漏? [英] C++ Screen capture fail after hundreds repetitions on Windows: memory leak?

查看:246
本文介绍了C ++在Windows上数百次重复后屏幕捕获失败:内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用一个使用 BitBlt mehtod捕获屏幕的函数,然后可以返回 HBITMAP p>

  int screenCapture(){
int width = 1000;
int height = 700;

HDC hdcTemp,hdc;
BYTE * bitPointer;

hdc = GetDC(HWND_DESKTOP); $ b $ h hdcTemp = CreateCompatibleDC(hdc);

BITMAPINFO bitmap;
bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
bitmap.bmiHeader.biWidth = width;
bitmap.bmiHeader.biHeight = -height;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 24;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = 0;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;
HBITMAP hBitmap = CreateDIBSection(hdcTemp,& bitmap,DIB_RGB_COLORS,(void **)(& bitPointer),NULL,NULL)
SelectObject(hdcTemp,hBitmap);
BitBlt(hdcTemp,0,0,width,height,hdc,0,0,SRCCOPY);
ReleaseDC(HWND_DESKTOP,hdc);
DeleteDC(hdcTemp);
return(int)bitPointer [0];
}

这里,函数只返回pixels数组的第一个值。 >
实际上,它工作正常。

  for(int i = 0; i> = 0; i ++) {
cout<< i<< :<< screenCapture()<< endl;
}

但是当我尝试循环时,会在几百($ 900),一个访问冲突读取位置错误。



我也注意到if我减少了 width height 的值,那么错误需要更长时间才能调用。



我是一个真正的初学者,我不知道错误可能会发生在哪里,但它看起来像一个内存问题,对吧?

解决方案

正如评论中所述,您泄漏了您的 HBITMAP ,以及原始的 HBITMAP SelectObject()之前已经在 HDC 中的c $ c>。每当您使用 SelectObject()时,您必须始终还原原始值(您不拥有它)。



 <$ c> 

$ c> int screenCapture()
{
int result = -1;

int width = 1000;
int height = 700;

HDC hdcTemp,hdc;
BYTE * bitPointer;

hdc = GetDC(HWND_DESKTOP);
if(hdc!= NULL)
{
hdcTemp = CreateCompatibleDC(hdc);
if(hdcTemp!= NULL)
{
BITMAPINFO bitmap;
bitmap.bmiHeader.biSize = sizeof(Bitmap.bmiHeader);
bitmap.bmiHeader.biWidth = width;
bitmap.bmiHeader.biHeight = -height;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 24;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = 0;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;

HBITMAP hBitmap = CreateDIBSection(hdcTemp,& bitmap,DIB_RGB_COLORS,(void **)& bitPointer,NULL,NULL);
if(hBitmap!= NULL)
{
HBITMAP hPrevBitmap = SelectObject(hdcTemp,hBitmap);

BitBlt(hdcTemp,0,0,width,height,hdc,0,0,SRCCOPY);
result =(int)bitPointer [0];

SelectObject(hdcTemp,hPrevBitmap);
DeleteObject(hBitmap);
}

DeleteDC(hdcTemp);
}

releaseDC(HWND_DESKTOP,hdc);
}

返回结果;
}


I use a function which captures a screen using the BitBlt mehtod and can then return a HBITMAP.

int screenCapture() {
    int width = 1000;
    int height = 700;

    HDC hdcTemp, hdc;
    BYTE* bitPointer;

    hdc = GetDC(HWND_DESKTOP);
    hdcTemp = CreateCompatibleDC(hdc);

    BITMAPINFO bitmap;
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
    bitmap.bmiHeader.biWidth = width;
    bitmap.bmiHeader.biHeight = -height;
    bitmap.bmiHeader.biPlanes = 1;
    bitmap.bmiHeader.biBitCount = 24;
    bitmap.bmiHeader.biCompression = BI_RGB;
    bitmap.bmiHeader.biSizeImage = 0;
    bitmap.bmiHeader.biClrUsed = 0;
    bitmap.bmiHeader.biClrImportant = 0;
    HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
    SelectObject(hdcTemp, hBitmap);
    BitBlt(hdcTemp, 0, 0, width, height, hdc, 0, 0, SRCCOPY);
    ReleaseDC(HWND_DESKTOP, hdc);
    DeleteDC(hdcTemp);
    return (int)bitPointer[0];
}

Here, the function only returns the first value of the pixels array.
Actually, it works fine.

for (int i = 0; i >= 0; i++) {
        cout << i << ": " << screenCapture() << endl;
    }

But when I try to loop this, an error is generated after a few hundred rounds (a little over 900 for me), an Access violation reading location error.

I also noticed that if I reduced the values of width and height, then the error took longer to be called.

I am a true beginner and I do not know where the error may come, but it would look like a memory problem, right?

解决方案

As was stated in comments, you are leaking your HBITMAP, and also the original HBITMAP that was already in the HDC before you called SelectObject(). Whenever you use SelectObject(), you must always restore the original value (you don't own it).

And don't forget to do error checking!

Try this:

int screenCapture()
{
    int result = -1;

    int width = 1000;
    int height = 700;

    HDC hdcTemp, hdc;
    BYTE* bitPointer;

    hdc = GetDC(HWND_DESKTOP);
    if (hdc != NULL)
    {
        hdcTemp = CreateCompatibleDC(hdc);
        if (hdcTemp != NULL)
        {
            BITMAPINFO bitmap;
            bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
            bitmap.bmiHeader.biWidth = width;
            bitmap.bmiHeader.biHeight = -height;
            bitmap.bmiHeader.biPlanes = 1;
            bitmap.bmiHeader.biBitCount = 24;
            bitmap.bmiHeader.biCompression = BI_RGB;
            bitmap.bmiHeader.biSizeImage = 0;
            bitmap.bmiHeader.biClrUsed = 0;
            bitmap.bmiHeader.biClrImportant = 0;

            HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)&bitPointer, NULL, NULL);
            if (hBitmap != NULL)
            {
                HBITMAP hPrevBitmap = SelectObject(hdcTemp, hBitmap);

                BitBlt(hdcTemp, 0, 0, width, height, hdc, 0, 0, SRCCOPY);
                result = (int) bitPointer[0];

                SelectObject(hdcTemp, hPrevBitmap);
                DeleteObject(hBitmap);
            }

            DeleteDC(hdcTemp);
       }

       ReleaseDC(HWND_DESKTOP, hdc);
    }

    return result;
}

这篇关于C ++在Windows上数百次重复后屏幕捕获失败:内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆