CListCtrl => LVITEM memorymanagment!? (und userdata)



  • Gutem Leute,

    wie wird den in enem MFC CListCtrl die Items "intern" gespeichert?

    Das Control stellt mir ja eine Methode

    int InsertItem(_In_ const LVITEM* pItem);
    

    zur Verfügung.

    Wenn ich nun bspw. sowas mache:

    LVITEM item;
    item.item = 0;
    item.pszText = _T("test");
    item. lParam = (LPARAM)new UserDATA();
    myctrl->InsertItem(&item);
    

    wird ja pszTest und lParam als pointer auf meine userdata und des string im LVITEM hinteregt.

    was passiert nun im InsertItem? wird da eine LVITEM copy angelegt? oder muss ich LVITM auf dem heap
    anlegen und selber bei remove Item wieder löschen?
    Selbst wenn dieses Struktur intern kopiert wird, muss ich meine userData (lParam) trotzdem irgendwie freigeben wenn ich das Element aus der Liste lösche?

    Danke , hoffe ich konnte es verständlich formulieren:)



  • Intern wird eine Kopie von dem LVITEM angelegt (denn CListCtrl benötigt ja für die Items selber eine dynamische Struktur - da die Anzahl der Items ja beliebig groß sein kann). Würde es direkt nur den Zeiger verwenden, dann gäbe es bei lokalen Variablen ja einen "dangling pointer".
    Und selbstverständlich muß man als Anwender jede dynamische Allokation (mittels new - könnte aber auch z.B. per malloc passieren) selber wieder freigeben. Man könnte ja auch einfach einen Zahlenwert als lParam übergeben - diese Unterscheidung kann das Control ja nicht kennen.

    Gleiches gilt natürlich auch für pszText (u.a.) , falls man diesen dynamisch alloziert.



  • Super vielen Dank,

    aber da habe ich noch ne frage: Es gibt ja noch eine AddItem override

    int InsertItem(_In_ int nItem, _In_z_ LPCTSTR lpszItem);
    

    unter der Haube wird da ja vermutlich auch ein LVITEM erstellt!?

    wenn ich hier ein _T("FOO") als LPCSTR übergebe, wird diese dann auch intern kopiert und nochmal kopiert,
    und der pointer auf den string inter wieder automatisch freigegben?



  • Nein, da wird nur der Zeiger direkt eingetragen (und nicht der ganze String kopiert).
    Bei String-Literalen ist das ja auch kein Problem, nur (die Adresse von) lokale Arrays sollte man nicht verwenden.



  • @Th69 sagte in CListCtrl => LVITEM memorymanagment!? (und userdata):

    Nein, da wird nur der Zeiger direkt eingetragen (und nicht der ganze String kopiert).
    Bei String-Literalen ist das ja auch kein Problem, nur (die Adresse von) lokale Arrays sollte man nicht verwenden.

    hmm das verstehe ich nich ganz, d.h. bedeutet ich allokiere den speicher für den string und übergeben einen zeiger.

    aber wer löscht den string wieder wenn das item removed wird?



  • Das muß dann wieder zusätzlich zu (d.h. vor) RemoveItem geschehen (sofern es eine dynamische Allokation ist).



  • @Th69 sagte in CListCtrl => LVITEM memorymanagment!? (und userdata):

    (sofern es eine dynamische Allokation ist).

    ok das verstehe ich, aber ich hätte jetzt quasi item list als viewmodel /backingfield verwendet, will ja nicht außerhalb zusätzlich ne liste führen wo ich die string hinterlegt habe, und davon dann nur die ptr dem control übergebe.. oder?

    ehr ne design frage



  • Da du von ViewModel sprichst: doch, man würde eine eigene Liste für die Texte (und andere Infos) anlegen. LVITEM ist ja eine Control-abhängige Struktur (UI).



  • @Th69 sagte in CListCtrl => LVITEM memorymanagment!? (und userdata):

    Da du von ViewModel sprichst: doch, man würde eine eigene Liste für die Texte (und andere Infos) anlegen. LVITEM ist ja eine Control-abhängige Struktur (UI).

    ok super danke, um es zusammenfassen:

    • LVITEM wird intern kopiert, aber nicht die ptr bezogene speicher bereiche.

    • custom data (LPARAM) muss ich miss das freigeben sofern LPARAM == ptr is selbst kümmern.

    • auch die Texte /String werden von außen als LPCSTR übergeben und müssen auch wieder von außen freigegeben werden

    so danke



  • Schau die mal den Virtual Model an, gerade wenn du eh eine eigenes Viewmodel verwendest.


Anmelden zum Antworten