MFC C ++ CListCtrl - удаление всех элементов не освобождает память - PullRequest
0 голосов
/ 27 сентября 2018

Совсем не эксперт в MFC, но меня привлекли к проекту по обновлению графического интерфейса в одном из наших приложений.Я строю диалог с помощью CListCtrl и вижу проблемы с памятью, хотя список, который я показываю, обычно содержит не более 200 строк.Есть 4 столбца, и я присоединяю связанное значение int к каждой строке, используя SetItemData для выполнения фильтрации.

Когда я фильтрую, я заново заполняю список, сначала вызывая DeleteAllItems (), а затем зацикливаясь, чтобы заполнитьтолько с данными, которые проходят мой фильтр.Когда я наблюдаю на вкладке «Быстродействие» в диалоговом окне «Диспетчер системных задач», я вижу, что память открывается при открытии диалогового окна.Кажется, больше, чем я себе представляю, но все равно.Когда я выполняю фильтрацию, если в результате выбранного фильтра ничего не отображается, система никогда не освобождает память, согласно вкладке «Производительность диспетчера задач».Когда я изменяю фильтр, чтобы показать некоторые строки, я вижу, что больше памяти занято.Я никогда не вижу память, возвращенную системе.Если я продолжу фильтровать, я в конечном итоге увижу, что использование памяти почти полностью занято, и я получу диалоговое окно «Недостаточно памяти», которое выдает MFC.

Я видел это диалоговое окно нехватки памяти также, когдаЯ просто прокручиваю вверх и вниз в полном (нефильтрованном) виде данных.Для каждой прокрутки элемент управления списком несколько медленно перерисовывается, и использование памяти на вкладке «Производительность» возрастает, хотя я не добавляю никаких данных.

Есть ли у кого-нибудь ощущение того, что может произойтиЗдесь?Я в тупике на данный момент.Ниже в основном то, что я делаю в своем коде.Я не управляю другим видом:

m_ListCtrl.DeleteAllItems();
for (int i=0; i<mylist.size(); i++)
{
    // here I get all the data from the current record in mylist, one of them being an int value iSecs.
    ...

    // insert data item
    int row = m_ListCtrl.InsertItem(i, sTimeStamp.c_str());
    BOOL ok = m_ListCtrl.SetItem(i, 1, sErrorCode.c_str());
    ok = m_ListCtrl.SetItem(i, 2, sErrorLevel.c_str());
    ok = m_ListCtrl.SetItem(i, 3, sDescription.c_str());
    // set the timestamp seconds as item data for later filtering for display
    ok = m_ListCtrl.SetItemData(row, (DWORD_PTR)iSecs);
}

1 Ответ

0 голосов
/ 27 сентября 2018

Память кучи обычно не возвращается в ОС при вызове free () (или delete).Он сохраняется в куче.Смотри также этот ответ .Таким образом, при первой операции заполнения / удаления всех вы увидите увеличение выделенной памяти.Но на последующих циклах использование памяти должно быть достаточно стабильным.

Библиотеки MFC от Microsoft существуют уже более десяти лет, если в CListCtrl :: DeleteAllItems () была утечка памятиэто было бы найдено в 90-х годах.

Вы можете проверить использование памяти в программе с помощью нескольких вызовов API .

Утечка памяти, вероятно, вызвана этой строкой:

ok = m_ListCtrl.SetItemData(row, (DWORD_PTR)iSecs);

В элементе данных MFC пользователь несет ответственность за очистку.Вам нужно будет перебирать каждый элемент в вашем списке, освобождая (или удаляя) пользовательские данные, прежде чем вызывать API для удаления элемента (ов) списка.Конечно, вы можете освободить распределенные данные и другим способом.

...