Этот код съедает мою оперативную память со скоростью 1-2 процента в секунду (всего 6 ГБ). Может ли кто-нибудь сказать мне, что случилось? Заранее спасибо. Я новичок в этом, так что если я звучу как полный идиот, то это так. Мне нужен быстрый ответ.

        #include <windows.h>
    #include <iostream>
    #include <stdio.h>

    using namespace std;

    /* Globals */
    int ScreenX = 0;
    int ScreenY = 0;
    BYTE* ScreenData = 0;

    void ScreenCap()
    {
        HDC hScreen = GetDC(GetDesktopWindow());
        //hScreen2 = hScreen;

        if (ScreenX == 0)
        {
            ScreenX = GetDeviceCaps(hScreen, HORZRES);
            ScreenY = GetDeviceCaps(hScreen, VERTRES);
        }

        HDC hdcMem = CreateCompatibleDC (hScreen);
        HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, ScreenX, ScreenY);
        HGDIOBJ hOld = SelectObject(hdcMem, hBitmap);
        BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hScreen, 0, 0, SRCCOPY);
        SelectObject(hdcMem, hOld);

        BITMAPINFOHEADER bmi = {0};
        bmi.biSize = sizeof(BITMAPINFOHEADER);
        bmi.biPlanes = 1;
        bmi.biBitCount = 32;
        bmi.biWidth = ScreenX;
        bmi.biHeight = -ScreenY;
        bmi.biCompression = BI_RGB;
        bmi.biSizeImage = 0;// 3 * ScreenX * ScreenY;

        if(ScreenData)
            free(ScreenData);
        ScreenData = (BYTE*)malloc(4 * ScreenX * ScreenY);

        GetDIBits(hdcMem, hBitmap, 0, ScreenY, ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);

        ReleaseDC(GetDesktopWindow(),hScreen);
        DeleteDC(hdcMem);
    }

    inline int PosB(int x, int y)
    {
        return ScreenData[4*((y*ScreenX)+x)];
    }

    inline int PosG(int x, int y)
    {
        return ScreenData[4*((y*ScreenX)+x)+1];
    }

    inline int PosR(int x, int y)
    {
        return ScreenData[4*((y*ScreenX)+x)+2];
    }

    bool ButtonPress(int Key)
    {
        bool button_pressed = false;

        while(GetAsyncKeyState(Key))
            button_pressed = true;

        return button_pressed;
    }

    int main()
    {
        while (true)
        {
            ScreenCap();

            /*for (int x = 1; x < ScreenX; x++)
            {
                for (int y = 1; y < ScreenY; y++)
                {
                    int Red = PosR(x, y);
                    int Green = PosG(x, y);
                    int Blue = PosB(x, y);

                    if (Red == 22 && Green == 58 && Blue == 89)
                    {
                        cout << ">:D";
                        POINT pos;
                        GetCursorPos(&pos);

                        int DX = 683 - x;
                        int DY = 683 - y;

                        /*COLORREF col = GetPixel(hScreen2, DX - pos.x + 1, pos.y - DY + 1);

                        int red = GetRValue(col);
                        int blue = GetBValue(col);
                        int green = GetGValue(col);

                        if (red == 22 && green == 58 && blue == 89)
                        {
                            break;
                        }

                        //SetCursorPos(x + DX, y + DY);
                        SetCursorPos(DX - pos.x + 1, pos.y - DY + 1);
                        cout << DX - pos.x << ", " << pos.y - DY + 1 << endl;
                        break;
                    }
                }
            }*/
        }

        system("PAUSE");
        return 0;
    }
0
user3103398 15 Дек 2013 в 04:19

1 ответ

Лучший ответ

Вы продолжаете создавать новые растровые изображения и никогда не удаляете их.

Даже лучше, чем освобождать их каждый раз, было бы повторно использовать предыдущее растровое изображение, если только размер экрана не изменился. То же для ScreenData. Излишнее перераспределение снижает производительность.

Вы также не выбираете исходный объект, прежде чем уничтожить DC, что является проблемой.

2
Ben Voigt 15 Дек 2013 в 04:25
Так как мне их удалить? Как я уже сказал, я идиот.
 – 
user3103398
15 Дек 2013 в 04:27
Ненавижу спрашивать, но это мой последний вопрос (надеюсь). Можете выложить измененную версию? Надеюсь, это не так уж и много.
 – 
user3103398
15 Дек 2013 в 04:30
Документация на CreateCompatibleBitmap должна указать вам на DeleteObject, функцию удаления растрового изображения. На MSDN не было образца?
 – 
Ben Voigt
15 Дек 2013 в 04:32