Problem mit realloc und LPARAM aus ListView
-
Hallo zusammen,
ich habe eine Strucktur die ich als Array verwende. Da ich die größe der Array nicht kenne erweiter ich die Array mit realloc um ein Element.
es speichert auch alles wunderbar in der Struckturierten Array. nur läst sich die mit realloc erstellte Array nicht mehr als Adresse an das LPARAM eine ListView hängen.
Bzw. hinhängen kann ich sie schon ohne das ein Fehler passiert, nur wenn ich die Adresse der Strucktur wieder aus LPARAM abrufen will stehn da alles andere drinn, nur nicht das was ich ihr zugewiesen hab.weise ich der Struckturierten Array eine feste Größe zu, klapp alles ohne Probleme.
und bevor es zu missverständnissen kommt, m_SetupListCtrl ist eine von mir erstellte Classe unter verwendung der WINAPI.
hier meine Strucktur
typedef struct tagITEMFILEPARAM { char lpszItemToolTip[1024]; char lpszFilePath[MAX_PATH]; char lpszFileName[512]; char lpszFileExt[4]; }ITEMFILEPARAM; typedef UNALIGNED ITEMFILEPARAM * LPITEMFILEPARAM; static LPITEMFILEPARAM m_ipPL;hier weise ich der Strucktur eine neue Größe & einen Wert zu, und übergebe die Adresse an LParam.
m_ipPL = (LPITEMFILEPARAM) realloc (m_ipPL, (iIndex + 1) * sizeof(ITEMFILEPARAM)); strcpy(m_ipPL[iIndex].lpszFilePath,lpFileName); LVITEM LvItem; memset(&LvItem,0,sizeof(LvItem)); LvItem.mask = LVIF_PARAM; LvItem.iItem = iIndex; LvItem.lParam = (LPARAM)&m_ipPL[iIndex]; iIndex = m_SetupListCtrl.InsertItem(&LvItem);/**/so versuche ich die Adresse aus dem LParam wieder zu bekommen, leider stimmt die Adresse nicht.
LVITEM LvItem; memset(&LvItem,0,sizeof(LvItem)); LvItem.mask = LVIF_PARAM; LvItem.iItem = iItem; m_SetupListCtrl.GetItem(&LvItem); LPITEMFILEPARAM ip = (LPITEMFILEPARAM)LvItem.lParam; MsgBox(ip->lpszFilePath);weise ich aber der m_ipPL eine Feste Größe zu Zb. m_ipPL[1024] klappt alles einwandfrei.
weis jemand woran das liegt oder was ich falschmache?
-
Ist iIndex und iItem gleich?
-
ja die sind gleich,
ich klicke mit der rechten maustaste auf das element in der Listview und hole mir die Nr des Items.ich hab auch schon versucht in der Funktion in der ich mir das LPARAM aus der Liste holen will, mit
m_ipPL[iItem].lpszFilePathden wert anzeigen zu lassen und das klappt.
die werte werden also gespeichert.es speichert mir nur nicht die Adresse, bzw. wenn es eine Adresse speichert, ist diese Falsch.
-
Warum machst Du das überhaupt so kompliziert. Allokiere doch direkt einen Eintrag und setze das in den lParam Eintrag. Dann trägt jedes ListBox-Item den Zeiger selbst.
-
Allokiere doch direkt einen Eintrag und setze das in den lParam Eintrag
kann dir da gerade nicht folgen!
wie meinst du das?
-
Du trägst eine Index Position aus einem Array in dem Item ein.
Du könntest direkt einen Eintrag einzeln allokieren und diesen Zeiger in dem List View Item eintragen.BTW: Deine Strktur ist extrem speicherverwendend. Die Verwednung von CString oder std::string wäre effektiver.
-
MSDN (realloc) schrieb:
The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument.
Mit jedem realloc kann sich der Zeiger m_ipPL ändern, damit zeigen die im ListView-Item gespeicherten LPARAMs auf ungültige Bereiche.
Martin meint, dass Du beim Anlegen eines neuen Eintrags ein
ITEMFILEPARAM* pParam = (ITEMFILEPARAM*) malloc(sizeof(ITEMFILEPARAM));machen sollst und diesen dann lvItem.lParam zuweisen sollst. Damit es keine Speicherlecks gibt, solltest Du aber auch LVN_DELETEITEM abfangen und dort den Speicher wieder freigeben.