Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.11.2015, 11:20   #1
Boltina
Пользователь
 
Аватар для Boltina
 
Регистрация: 27.11.2014
Сообщений: 30
По умолчанию Небольшая утечка памяти в программе - C++

Ув. форумчане подскажите где в данном проекте может быть утечка памяти. Происходит медленно, но происходит. За но процесс стал кушать на 5-8 кб больше. Боюсь что со временем процесс не сможет работать, так как съест всю память.

Алгоритм работы программы: WinMain инициализирует параметры, запускается вечный цикл. В цикле: находим окно программы (если его нет, висим и ждём), далее захватываем окно, снимаем скриншот, выделяем из него определенные области, в них распознаем цифровые значения и записываем их в строку. Далее строку отправляем на обработку(удаление лишних символов и пробелов), после парсим строку и записываем в реестр значения из строки. Повторяем цикл сначала.
Мяу
Boltina вне форума Ответить с цитированием
Старый 27.11.2015, 11:25   #2
Boltina
Пользователь
 
Аватар для Boltina
 
Регистрация: 27.11.2014
Сообщений: 30
По умолчанию

Код:
//разрыв строки по delimiter(разделитель)
vector<string> split(const string str, char delimiter) {
    vector<string> internal;
    stringstream ss(str); // Turn the string into a stream.
    string tok;
    while (getline(ss, tok, delimiter)) {
        internal.push_back(tok);
    }
   return internal;
}
//получение скриншота окна
Mat get_screenshot(HWND parHwndFound)
{
    HWND hwndFound = parHwndFound;
    //проверка на свернутость окна
    if (IsIconic(hwndFound))
    {   //если свернуто - восстановим его
        BOOL is = ShowWindow(hwndFound, SW_SHOWNOACTIVATE);
        //SetForegroundWindow(hwndFound); - передать фокус окну
    }
    RECT rcSrc;//прямоугольник для снятия скриншота
    HDC hDC, hSrcDC;//вспомогательные контексты 
    HBITMAP hBmp;//изображение
    int Height, Width;
    //получить прямоугольник размером клиентской области окна
    GetClientRect(hwndFound, &rcSrc);   //GetWindowRect(hwndFound, &rcSrc);
    hDC = GetDC(hwndFound);//захват контекста окна
    hSrcDC = CreateCompatibleDC(hDC);
    Height = rcSrc.bottom - rcSrc.top;
    Width = rcSrc.right - rcSrc.left;
    hBmp = CreateCompatibleBitmap(hDC, Width, Height);
    SelectObject(hSrcDC, hBmp);
    PrintWindow(hwndFound, hSrcDC, PW_CLIENTONLY); 
    BITMAPINFO BMI;//задание параметров изображения
    BMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    BMI.bmiHeader.biWidth = Width;
    BMI.bmiHeader.biHeight = -Height;
    BMI.bmiHeader.biPlanes = 1;
    BMI.bmiHeader.biBitCount = 32;
    BMI.bmiHeader.biCompression = BI_RGB;
    Mat image = Mat(Height, Width, CV_8UC4);//изображение
    GetDIBits(hSrcDC, hBmp, 0, Height, image.data, &BMI, DIB_RGB_COLORS);
    // освобождаем ресурсы
    DeleteDC(hSrcDC);//очищаем рабочий контекст
    DeleteObject(hBmp);//очищаем изображение
    ReleaseDC(hwndFound, hDC);//отпускаем контекст программы
    return image;
}
 
//распознование цифр с рисунка
string recognPicture(Mat* pic) {
    //инициализация словаря
    tesseract::TessBaseAPI *myOCR =
        new tesseract::TessBaseAPI();
    if (myOCR->Init(NULL, NAME_TESSDATA)) {
        fprintf(stderr, "Could not initialize tesseract.\n");
        exit(1);
    }
    myOCR->SetImage((uchar*)pic->data, pic->size().width, pic->size().height, pic->channels(), pic->step1());
    myOCR->Recognize(0);
    string result = (const char*)myOCR->GetUTF8Text();
    myOCR->Clear();
    myOCR->End();
    return result;
}
 
#ifdef _UNICODE
#  define _tcout wcout
#else
#  define _tcout cout
#endif // _UNICODE
//запись в реестр параметр (название и значение)
int writeReg(string nameItem, string valueItem )
{
    // Устанавливаем русскую кодовую страницу для вывода кириллицы
    _tsetlocale(LC_ALL, _T("Russain"));
    // Строка которую будем писать в реестр   
    int wchars_num = MultiByteToWideChar(CP_UTF8, 0, nameItem.c_str(), -1, NULL, 0);
    wchar_t* wstr = new wchar_t[wchars_num];
    MultiByteToWideChar(CP_UTF8, 0, nameItem.c_str(), -1, wstr, wchars_num);
    // do whatever with wstr
    int wchars_num2 = MultiByteToWideChar(CP_UTF8, 0, valueItem.c_str(), -1, NULL, 0);
    wchar_t* wstr2 = new wchar_t[wchars_num2];
    MultiByteToWideChar(CP_UTF8, 0, valueItem.c_str(), -1, wstr2, wchars_num2);
    // Ключ который будем создавать
    //_TCHAR szPath[] = _T("Software\\Dispetcher\");
    HKEY hKey;
    // Создаем ключ в ветке HKEY_CURRENT_USER
    if (RegCreateKeyEx(HKEY_CURRENT_USER, SZPATH, 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) {
        _tcout << _T("При создании ошибка") << endl;
        return 1;
    }
    // Пишем тестовую строку в созданный ключ
    if (RegSetValueEx(hKey, wstr, 0, REG_SZ, (BYTE*)wstr2, sizeof(wstr2)*wchars_num2) != ERROR_SUCCESS) {
        _tcout << _T("При записи ошибка") << endl;
        return 2;
    }
    // Закрываем описатель ключа
    if (RegCloseKey(hKey) != ERROR_SUCCESS) {
        _tcout << _T("При закрытии ошибка") << endl;
        return 3;
    };
    delete[] wstr;
    delete[] wstr2;
    return 0;
}
 
//приведение строки в нормальный вид(остаются только цифры и . )
string normalizeString(string stringParam)
{string str;
    for (int i = 0; i < stringParam.length(); i++)
    {
        if (isdigit(stringParam[i]) || (stringParam[i] == VLUES_SEPARATOR) || (stringParam[i] == DECIMAL_POINT))
        {
            str = str + stringParam[i];
        }
    }
    return str;
}
 
//обработка строки,выделение значения каждого параметра и запись его в реестр
void processingString(string stringParam)
{
    //убираем лишние знаки и символы из строки
    //разбиваем строку и пишем в реестр
    vector<string> items;
    items = split(normalizeString(stringParam), VLUES_SEPARATOR);
    int i = 0;
    for (vector<string>::iterator it = items.begin(); it != items.end(); ++it)
    {   
        writeReg(NODES[i], *it);
        i++;
    }
}
Мяу
Boltina вне форума Ответить с цитированием
Старый 27.11.2015, 11:26   #3
Boltina
Пользователь
 
Аватар для Boltina
 
Регистрация: 27.11.2014
Сообщений: 30
По умолчанию

Сверху вызываемые процедуры. Снизу главная процедура
Код:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstanse, LPSTR LpszCmdParam, int nCmdShow)
{
    Sleep(10 * 1000);
    HWND hwndFound;
    Mat imageMat;
    vector<string> coordinates;//координаты позиций 
    vector<string> rect;//вектор для 4ех координат 
    string strParam;
    int x, y, width, height;
    Rect roi;// = Rect(0,0,0,0);
    Mat subM;
    string s;
    ifstream fin(BLOCK_POSITION); // открыли файл для чтения
    if (fin.is_open())
    {
        while (getline(fin, s)) coordinates.push_back(s);
        fin.close(); // закрываем файл
    }
    while (1) {
        //находим окно
        hwndFound = FindWindow(NULL, WINDOW_TITLE);
        if (hwndFound == NULL) {
            Sleep(5 * 1000);
            continue;//если не найдено пропускаем цикл
        }
        //получение изображения окна
        imageMat = get_screenshot(hwndFound);
        //перебрать все координаты 
        for (vector<string>::iterator it = coordinates.begin(); it != coordinates.end(); ++it)
        {
            rect = split(*it, COORDINATES_SEPARATOR);//выделяем из строки 4е координаты
            x = stoi(rect.at(0));//позиция Х
            y = stoi(rect.at(1)) + 45;//позиция У
            width = stoi(rect.at(2));//ширина
            height = stoi(rect.at(3));//высота
            roi = Rect(x, y, width, height);
            subM = imageMat(roi);
            strParam = strParam + recognPicture(&subM) + VLUES_SEPARATOR;//распознаем и добавляем в строку числовые значения из прямоугольной области       
            rect.clear();//чистим координаты
            ~subM;
        }
 
        //обработка строки с числовыми значениями
        processingString(strParam);
        strParam.clear();
        strParam.~basic_string();
        imageMat.release();
    Sleep(15*1000);
    }
    return 0;
}
Мяу
Boltina вне форума Ответить с цитированием
Старый 27.11.2015, 15:26   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Я не очень смотрел, но я вижу myOCR = new... но не вижу delete myOCR
waleri вне форума Ответить с цитированием
Старый 27.11.2015, 15:47   #5
Boltina
Пользователь
 
Аватар для Boltina
 
Регистрация: 27.11.2014
Сообщений: 30
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Я не очень смотрел, но я вижу myOCR = new... но не вижу delete myOCR
Код:
string recognPicture(Mat* pic) {
	char outText[10];
	//инициализация словаря
	tesseract::TessBaseAPI *myOCR =
		new tesseract::TessBaseAPI();
	if (myOCR->Init(NULL, NAME_TESSDATA)) {
		fprintf(stderr, "Could not initialize tesseract.\n");
		exit(1);
	}
	myOCR->SetImage((uchar*)pic->data, pic->size().width, pic->size().height, pic->channels(), pic->step1());
	myOCR->Recognize(0);

	strcpy(outText, myOCR->GetUTF8Text());
	string result(outText);

	myOCR->Clear();
	myOCR->End();
	delete [] outText;
	delete myOCR;

	return result;
}
Немножко подправил процедуру. Но на delete myOCR; вышибает ошибка
Мяу
Boltina вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
утечка памяти polin11 Общие вопросы C/C++ 10 18.08.2015 18:12
Небольшая утечка памяти с TStringList Pcrepair Общие вопросы Delphi 10 19.03.2013 10:20
утечка памяти Кудаив Помощь студентам 1 30.04.2012 18:18
Утечка памяти forivanb Общие вопросы Delphi 4 11.04.2012 15:28
Утечка памяти ZvEr_HaCkEr Свободное общение 13 24.09.2010 19:30