Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > ImageList и освобождение памяти


Автор: Letchik 1.6.2010, 10:07
Привет!
У меня к вам просьба!
Объясните пожалуйста, почему после закрытия диалогового окна память не освобождается? Правда есть плюс, после повторного его открытия, память заново не выделяется.
А вот очень важная проблема: в диалоговом окне есть массив из ImageList"ов. Создаю с помощью ImageList_Create(), а в обработчике WM_DESTROY удаляю их всех с помощью ImageList_Destroy. Однако память после них не освобождается. Мало того, с каждым открытием окна память под них только выделяется.
Проверил, это именно ImageList!
Количество выделяемой памяти наблюдаю в диспетчере задач.
В чём дело? 
Чего я не знаю?

Автор: Alca 1.6.2010, 10:41
 smile  где код?

Автор: Letchik 1.6.2010, 18:31
Код

    case WM_CREATE:
               /*.....some code....*/   
                    
        BUTTON_IMAGELIST btimg;                         //Параметры отображения иконок на кнопках
        btimg.margin.left = 20;
        btimg.margin.top = 0;
        btimg.margin.right = -25;
        btimg.margin.bottom = 0;
        btimg.uAlign = BUTTON_IMAGELIST_ALIGN_LEFT;                           

         for (int i = 0; i < 4; i++)                 //В цикле подгружаются иконки
        {
            hImgList[i] = ImageList_Create(20, 20, ILC_COLOR32 | ILC_MASK, 1, 0); //Создаём имедэлист
            hIcon = ExtractIcon(hInst, _T("iclib.dll"), i + 6);                                          //Грузим иконку
            ImageList_AddIcon(hImgList[i], hIcon);                                                   //   Добавляем иконку в имиджлист
            btimg.himl = hImgList[i];                                                                          //Ну а тут
            Button_SetImageList(hNContact_Button[i], &btimg);                              //присваиваем иконку кнопке
        }
        
        DeleteObject(hIcon);

                            /*....some code.....*/

        ShowWindow(hNContact, TRUE);
        UpdateWindow(hNContact);
        break;

    case WM_COMMAND:
        
        switch (wParam)
        {
        case IDM_CONTACT_CANCEL:                              //Тут всё ясно
            DestroyWindow(hNContact);
            break;
        }
        break;

    case WM_DESTROY:
        
        for (int i = 0; i < 4 i++)                                         //Цикл для удаления (!) Всех имеющихся имиджлистов
        {
            ImageList_RemoveAll(hImgList[i]);
            ImageList_Destroy(hImgList[i]);
        }
        break;
 
Вот уменьшённая версия кода. Вместо "some code" кое-какие строчки отвечающие за создание контролов, установка шрифтов и тому подобное. С этим проблем нет.

Автор: xvr 1.6.2010, 21:59
IMHO тут проблема не в ImageList, а в Icon. В строке 14 создается 4 иконки, а в строке 20 удаляется только одна.

Автор: Letchik 2.6.2010, 13:40
Я тоже так думал. Чтобы проверить, вставил DeleteObject(hIcon) в цикл. Проблема не решилась.
Потом убрал из цикла все строки кроме   
Код

hImgList[i] = ImageList_Create(20, 20, ILC_COLOR32 | ILC_MASK, 1, 0);
 
Проблема повторилась. Затем убрал всю часть кода, которая отвечала за загрузку картинок, создание имиджлистов и тому подобное.
Результат: память выделялась только при первом открытии диалогового окна.
Вывод: дело в ImageList.

Автор: GremlinProg 2.6.2010, 14:06
Цитата(Letchik @  2.6.2010,  15:40 Найти цитируемый пост)
Я тоже так думал. Чтобы проверить, вставил DeleteObject(hIcon) в цикл. Проблема не решилась.

если иконка не общая(LR_SHARED), ее нужно удалять с помощью DestroyIcon

Автор: Dem_max 2.6.2010, 20:13
менеджер памяти не охотно хочет уменьшать память кучи после уничтожения Image List с его содержимым.

Автор: GremlinProg 3.6.2010, 09:21
Цитата(Dem_max @  2.6.2010,  22:13 Найти цитируемый пост)
менеджер памяти не охотно хочет уменьшать память кучи после уничтожения Image List с его содержимым.

это не проблема кучи,
физическое освобождение памяти происходит только при ее дефиците,
иначе бы все операции с памятью требовали бы гораздо больше времени,
так что в данном случае "невысвобождение памяти" - не показатель

показатель - постоянный рост задействованных ресурсов, т.е. утечка (leak)

Автор: Letchik 3.6.2010, 21:29
Диагноз - утечка памяти.
Не пойму, откуда берутся целых 32кб????  И почему память не освобождается после закрытия окна????  smile
Конечно, на практике это никак не отразится на производительности программы, особенно на современных компьютерах. Ведь для того, чтобы в памяти собрался лишний мегабайт мусора нужно открыть окошко 32 раза. Вряд ли такое случится, но тем не менее, мне очень не нравится, что моя прога страдает утечкой памяти...
Неужели никто не сталкивался с данной проблемой???

Автор: Dem_max 4.6.2010, 04:37
у меня та же самая проблема, память выделяется, но диспечер задач показывает как будто она не освободилась. При следующем создании ImageList, память не увеличивается - это не есть утечка памяти. Утечка это когда постоянно память будет увеличиваться.

Автор: Letchik 7.6.2010, 07:39
А вот у меня увеличивается...
Покажи код  smile 

Автор: Dem_max 7.6.2010, 08:54
Собственно только вот это


Код

hImList = ImageList_Create(cx, cy, ILC_COLOR32 | ILC_MASK, 6, 0);

ImageList_AddIcon(hImList, hIcon); 
ImageList_AddIcon(hImList, hIcon); 
ImageList_AddIcon(hImList, hIcon);  


ImageList_Destroy(hImList);

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)