簡體   English   中英

MFC C++ CListCtrl - 刪除所有項目不回收內存

[英]MFC C++ CListCtrl - deleting all items does not reclaim memory

我根本不是 MFC 方面的專家,但我已經參與了一個項目,要在我們的一個應用程序中改進 GUI。 我正在使用 CListCtrl 構建一個對話框並看到內存問題,即使我顯示的列表通常包含不超過 200 行。 有 4 列,我使用 SetItemData 為每一行附加一個關聯的 int 值,以便進行過濾。

過濾時,我首先調用 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);
}

當調用 free()(或 delete)時,堆內存通常不會返回給操作系統。 它保留在堆中。 另請參閱此答案 因此,在第一次填充/刪除所有操作時,您將看到分配的內存增加。 但是在隨后的循環中,內存使用應該相當穩定。

Microsoft 的 MFC 庫已經存在了十多年,如果CListCtrl::DeleteAllItems() 中存在內存泄漏,它就會在 90 年代被發現。

您可以通過一些 API 調用在程序中檢查內存使用情況。

內存泄漏可能是由這一行引起的:

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

在 MFC 中,項目數據是用戶負責清理的。 在調用 API 刪除列表項之前,您需要遍歷列表中的每個項以釋放(或刪除)用戶數據。 當然,您也可以通過其他方式釋放分配的數據。

隨着您的程序不斷從列表中添加和刪除項目,它會泄漏與每個列表條目相關聯的 ItemData(s)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM