[英]The C++ Code has a memory leak I that i can't fix
我正在尝试创建一个简单的机器人来测试我的技能。 它可以在短时间内正常工作,然后崩溃。 它有一个奇怪的 memory 泄漏,我无法理解。 任何帮助,将不胜感激。
有关代码的额外信息。 它截取屏幕上某些区域的屏幕截图,并比较图像上 4 个像素的 colors,当它看到一个暗像素时,它会自行按下相应的按钮。 是的,我正在尝试使用 c++ 中的钢琴瓷砖机器人 :)
[#include <windows.h>
int R\[4\];
int G\[4\];
int B\[4\];
COLORREF cRef\[4\];
void ScreenShot() {
HWND DesktopHwnd = GetDesktopWindow();
RECT DesktopParams;
HDC DevC = GetDC(DesktopHwnd);
GetWindowRect(DesktopHwnd, &DesktopParams);
DWORD Width = DesktopParams.right - DesktopParams.left;
DWORD Height = DesktopParams.bottom - DesktopParams.top;
DWORD FileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (sizeof(RGBTRIPLE) + 1 * (Width * Height * 4));
char* BmpFileData = (char*)GlobalAlloc(0x0040, FileSize);
//std::cout << (BmpFileData);
PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
PBITMAPINFOHEADER BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData\[sizeof(BITMAPFILEHEADER)\];
BFileHeader->bfType = 'BM'; // BM
BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
BInfoHeader->biPlanes = 1;
BInfoHeader->biBitCount = 24;
BInfoHeader->biCompression = BI_RGB;
BInfoHeader->biHeight = Height - 1079;
BInfoHeader->biWidth = Width - 1522;
RGBTRIPLE *Image = (RGBTRIPLE*)&BmpFileData\[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)\];
//RGBTRIPLE color;
HDC CaptureDC = CreateCompatibleDC(DevC);
HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC, Width, Height);
SelectObject(CaptureDC, CaptureBitmap);
BitBlt(CaptureDC, -753, -566, Width, Height, DevC, 0, 0, SRCCOPY | CAPTUREBLT);
GetDIBits(CaptureDC, CaptureBitmap, 0, Height, Image, (LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);
for (size_t i = 0; i < 4; i++)
{
cRef\[i\] = GetPixel(CaptureDC, (100 * i) + 2, 0);
}
for (size_t i = 0; i < 4; i++)
{
R\[i\] = GetRValue(cRef\[i\]);
G\[i\] = GetGValue(cRef\[i\]);
B\[i\] = GetBValue(cRef\[i\]);
}
}
int main()
{
// This structure will be used to create the keyboard
// input event.
INPUT ip;
// Pause for 5 seconds.
Sleep(3000);
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
while (true)
{
ScreenShot();
for (size_t i = 0; i < 4; i++)
{
if (R\[i\] == 17 && B\[i\] == 17 && G\[i\] == 17)
{
if (i == 0)
{
// Press the "A" key
ip.ki.wVk = 0x41; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release the "A" key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
}
if (i == 1)
{
// Press the "S" key
ip.ki.wVk = 0x53; // virtual-key code for the "S" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release the "S" key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
}
if (i == 2)
{
// Press the "D" key
ip.ki.wVk = 0x44; // virtual-key code for the "D" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release the "D" key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
}
if (i == 3)
{
// Press the "D" key
ip.ki.wVk = 0x46; // virtual-key code for the "D" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release the "D" key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
}
}
Sleep(2);
}
}
}]
您需要将此GlobalAlloc
与GlobalFree
匹配。 请参阅https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc
可能只是GlobalFree(BmpFileData);
在 function 的末尾。
您应该调用GlobalFree
的另一种方法是将其包装在 RAII 控制类型中: std::unique_ptr
。 第一部分很简单,这样做:
auto BmpFileData = std::unique_ptr<char>(GlobalAlloc(0x0040, FileSize));
会给你一个指向正确位置的指针,但是当它超出 scope 时,它会调用你不想要的常规delete
。 幸运的是,您可以忽略破坏:
auto BmpFileData = std::unique_ptr<char>(GlobalAlloc(0x0040, FileSize), GlobalFree);
应该为你工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.