I am trying to create a simple bot to test my skills on it. It works fine for a short time then it crashes. it has a weird memory leak which I can not understand how. Any help would be appreciated.
Extra info about the code. It takes a screenshot of the certain are on the screen and compares looks the colors of 4 pixels on the image and when it sees a dark pixel it presses the according button itself. Yes I'm trying to my a piano tiles bot in 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);
}
}
}]
You need to match this GlobalAlloc
with a GlobalFree
. See https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc
Possibly just GlobalFree(BmpFileData);
at the end of your function.
An alternative to calling GlobalFree
which you should be doing, is to wrap it up in a RAII controlled type: std::unique_ptr
. The first part is easy, doing this:
auto BmpFileData = std::unique_ptr<char>(GlobalAlloc(0x0040, FileSize));
Will get you a pointer, to the right place, but when it goes out of scope it will call a regular delete
which you don't want. Luckily, you can overide the destruction:
auto BmpFileData = std::unique_ptr<char>(GlobalAlloc(0x0040, FileSize), GlobalFree);
Should work for you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.