Задать вопрос
@mardokvk
Я junior-программист, мой профиль С#, изучаю С++.

Как понять что переполняет память в C++?

Моя ПО должно работать 24 часа в сутки, но после пары часов непрерывной работы оно выводит ПУСТОЕ окно Microsoft Visual C++ Runtime Library и программа больше не работает. Диспетчер задач пишет что потребление оперативной памяти в район 8-20 мб. Создаваемые объекты я удаляю через деструктор.

Я использую библиотеку GDI+
И с помощью неё сравниваю два изображения, одно скрин экрана, второе вырезанный кусочек я их называю шаблонами.

6905e253206ba527175406.png

Процесс создания изображений рабочего стола
class GDI_trinityWindow
{
public:
	HBITMAP hBitmap;
	RECT rc;
	ULONG_PTR gdiplusToken;
	GdiplusStartupInput gdiplusStartupInput;
	int Height, Widht;
	GDI_trinityWindow(wchar_t nameWindow[100])
	{
		HWND hWnd = FindWindow(nameWindow, 0);
		while (hWnd == NULL)
			hWnd = FindWindow(nameWindow, 0);

		SetWindowPos(hWnd, HWND_TOP, -8, -31, 0, 0, SWP_NOSIZE);
		GetWindowRect(hWnd, &rc);		
		GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

		Height = rc.bottom - 8;
		Widht = rc.right - 8;

		scrdc = GetDC(0);

		memdc = CreateCompatibleDC(scrdc);
		membit = CreateCompatibleBitmap(scrdc, Widht, Height);
		SelectObject(memdc, membit);
		BitBlt(memdc, 0, 0, Widht, Height, scrdc, 0, 0, SRCCOPY);
		hBitmap = (HBITMAP)SelectObject(memdc, membit);
	}
	~GDI_trinityWindow()
	{
		DeleteDC(scrdc);
		DeleteDC(memdc);
		DeleteObject(membit);
		DeleteObject(hBitmap);
		GdiplusShutdown(gdiplusToken);
	}
	void DeleteAllObject()
	{
		DeleteObject(scrdc);
		DeleteObject(memdc);
		DeleteObject(membit);
		DeleteObject(hBitmap);
	}
private:
	HDC scrdc, memdc;
	HBITMAP membit;
};


Метод в котором я использую получаемые данные

bool Search(Point& pt_firstpx, Point& pt_endpx, wchar_t* templateName)
{
	HWND hWnd = FindWindow(winEVEOnline_ClassName, NULL);
	SetForegroundWindow(hWnd);
	SetWindowPos(hWnd, HWND_TOP, -8, -31, 0, 0, SWP_NOSIZE);

	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR gdiplusToken;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

	GDI_trinityWindow GDI(winEVEOnline_ClassName);
	Bitmap bmp_trinity(GDI.hBitmap, NULL);
	int Height = bmp_trinity.GetHeight(), Width = bmp_trinity.GetWidth();

	bmp_trinity.Save(L"test.png", &png);

	ARGB_array argb;
	vector<ARGB_array> argb_arr = TemplateToVector(templateName);

	int A, R, G, B;
	Color clr;
	int D = 6; //D - Диапозон
	bool find = false;
	int coint = 0;
	for (int y = 0; y < bmp_trinity.GetHeight() && !find; y++)
		for (int x = 0; x < bmp_trinity.GetWidth() && !find; x++)
		{
			bmp_trinity.GetPixel(x, y, &clr);

			ARGBtoRGB(clr.GetValue(), A, R, G, B);
			if (R == argb_arr[0].Red && G == argb_arr[0].Green && B == argb_arr[0].Blue && !find)
				for (auto i : argb_arr)
				{
					bmp_trinity.GetPixel(x + i.pt.X - argb_arr[0].pt.X, y + i.pt.Y, &clr);
					ARGBtoRGB(clr.GetValue(), A, R, G, B);
					//if (R == i.Red && G == i.Green && B == i.Blue)
					if (R < (i.Red + D) && R >(i.Red - D) && G < (i.Green + D) && G >(i.Green - D) && B < (i.Blue + D) && B >(i.Blue - D))
					{
						bmp_trinity.SetPixel(x + i.pt.X - argb_arr[0].pt.X, y + i.pt.Y, Color::Green);
						//cout << i.pt.X << " - " << i.pt.Y << " [" << (int)i.Red << ":" << (int)i.Green << ":" << (int)i.Blue << "]" << endl;
						coint++;
					}
				}

			if (coint == argb_arr.size())
			{
				find = true;
				pt_firstpx.X = x;
				pt_firstpx.Y = y;
				pt_endpx.X = x + argb_arr[argb_arr.size() - 1].pt.X - argb_arr[0].pt.X;
				pt_endpx.Y = y + argb_arr[argb_arr.size() - 1].pt.Y;
			}
			else
				coint = 0;
		}

	if (find)
		cout << "find true" << endl;

	cout << coint << endl;
	cout << argb_arr.size() << endl;

	bmp_trinity.Save(L"test2.png", &png);

	GdiplusShutdown(gdiplusToken);
	return find;
}


Из интересного обнаружил это.

6907aeb4945ab358179228.png
  • Вопрос задан
  • 135 просмотров
Подписаться 1 Простой 2 комментария
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Разработчик C++
    9 месяцев
    Далее
  • Яндекс Практикум
    Разработчик C++ расширенный
    12 месяцев
    Далее
  • Яндекс Практикум
    Мидл разработчик С++
    4 месяца
    Далее
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
С чего вы взяли, что переполняется память? Если диспетчер задач пишет о всего-то 20мб?

Потребляет ли много памяти какой-то другой процесс?

Возможно там утечка каких-то ресурсов, вроде хендлов.

Каким-нибудь process explorer можно посмотреть сколько хендлов ваша программа имеет, если это число растет, надо разбираться, какие из виндовых объектов вы правильно не уничтожаете. Вроде бы все битмапы вы корректно уничтожаете через DeleteObject, возможно ошибка в другом коде.

Можно еще поробовать вашу программу подебажить. Вот когда окно вылезает, какой ваш код выполняется? Подключитесь к вашему процессу visual studio и смотрите. Или добавьте отладочный вывод, чтобы понять, какая функция начинает выполнятся но не заканчивает. Это подскажет вам, какие объекты вы не удалили правильно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы