C ++在Windows上数百次重复后屏幕捕获失败:内存泄漏? [英] C++ Screen capture fail after hundreds repetitions on Windows: memory leak?
问题描述
我使用一个使用 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屋!