std::sort() passes invalid parameter to sorting callback function
-
Hi, I use vector of pointers to my class to store data. I insert them using push_back(). Here is my function for inserting data into vector: [code] UINT CVirtualLWItemManager::insertItem(LS_item* pNewItem) { // check if current capacity is enough if (m_vecItems.size() > m_vecItems.capacity()) { AfxMessageBox("m_vecItems.size() > m_vecItems.capacity()"); return 0; } if (m_vecItems.size() == m_vecItems.capacity()) { // enlarge array m_vecItems.reserve(m_vecItems.capacity() + 128); // try again return insertItem(pNewItem); } m_vecItems.push_back(pNewItem); return 1; } [/code] Here is my function that launches std::sort(): [code] void CVirtualLWItemManager::sortItems(INT (*sort_cb)(LS_item*, LS_item*)) { std::sort(m_vecItems.begin(), m_vecItems.end(), sort_cb); } [/code] And here is my static sorting callback function: [code] INT CMyFileView::sortCallback(LS_item* pDataFirst, LS_item* pDataSecond) { ITEM_DESC* param1 = NULL; ITEM_DESC* param2 = NULL; param1 = (ITEM_DESC*) pDataFirst->lParam; param2 = (ITEM_DESC*) pDataSecond->lParam; INT iSortColumn = 0; if (getDoc()->iViewToSort == 1) iSortColumn = getDoc()->SortingColumnLeft; else iSortColumn = getDoc()->SortingColumnRight; // Nejdrive (..), pak adresar, dale soubor if (param1->folder > param2->folder) return -1; else if (param1->folder < param2->folder) return 1; // Trizeni podle zvoleneho sloupce switch (iSortColumn) { // ASCENDING case 0: // Podle nazvu souboru a adresaru return param1->name.CompareNoCase((LPCTSTR) param2->name); case 1: // Podle velikosti if(param1->size < param2->size) return -1; if(param1->size > param2->size) return 1; break; case 2: // Podle data if (param1->date < param2->date) return -1; if (param1->date > param2->date) return 1; break; // DESCENDING case 3: // Podle nazvu souboru a adresaru return (param1->name.CompareNoCase((LPCTSTR) param2->name)) * -1; case 4: // Podle velikosti if (param1->size < param2->size) return 1; if (param1->size > param2->size) return -1; break; case 5: // Podle data if (param1->date < param2->date) return 1; if (param1->date > param2->date) return -1; break; } return 0; } [/code] The problem is, sometimes pDataSecond parameter passed to this function has invalid parameter, eg. 0xfdfdfdfd. How is it possible? Objects that are inserted to the vector are created on the heap.
-
Hi, I use vector of pointers to my class to store data. I insert them using push_back(). Here is my function for inserting data into vector: [code] UINT CVirtualLWItemManager::insertItem(LS_item* pNewItem) { // check if current capacity is enough if (m_vecItems.size() > m_vecItems.capacity()) { AfxMessageBox("m_vecItems.size() > m_vecItems.capacity()"); return 0; } if (m_vecItems.size() == m_vecItems.capacity()) { // enlarge array m_vecItems.reserve(m_vecItems.capacity() + 128); // try again return insertItem(pNewItem); } m_vecItems.push_back(pNewItem); return 1; } [/code] Here is my function that launches std::sort(): [code] void CVirtualLWItemManager::sortItems(INT (*sort_cb)(LS_item*, LS_item*)) { std::sort(m_vecItems.begin(), m_vecItems.end(), sort_cb); } [/code] And here is my static sorting callback function: [code] INT CMyFileView::sortCallback(LS_item* pDataFirst, LS_item* pDataSecond) { ITEM_DESC* param1 = NULL; ITEM_DESC* param2 = NULL; param1 = (ITEM_DESC*) pDataFirst->lParam; param2 = (ITEM_DESC*) pDataSecond->lParam; INT iSortColumn = 0; if (getDoc()->iViewToSort == 1) iSortColumn = getDoc()->SortingColumnLeft; else iSortColumn = getDoc()->SortingColumnRight; // Nejdrive (..), pak adresar, dale soubor if (param1->folder > param2->folder) return -1; else if (param1->folder < param2->folder) return 1; // Trizeni podle zvoleneho sloupce switch (iSortColumn) { // ASCENDING case 0: // Podle nazvu souboru a adresaru return param1->name.CompareNoCase((LPCTSTR) param2->name); case 1: // Podle velikosti if(param1->size < param2->size) return -1; if(param1->size > param2->size) return 1; break; case 2: // Podle data if (param1->date < param2->date) return -1; if (param1->date > param2->date) return 1; break; // DESCENDING case 3: // Podle nazvu souboru a adresaru return (param1->name.CompareNoCase((LPCTSTR) param2->name)) * -1; case 4: // Podle velikosti if (param1->size < param2->size) return 1; if (param1->size > param2->size) return -1; break; case 5: // Podle data if (param1->date < param2->date) return 1; if (param1->date > param2->date) return -1; break; } return 0; } [/code] The problem is, sometimes pDataSecond parameter passed to this function has invalid parameter, eg. 0xfdfdfdfd. How is it possible? Objects that are inserted to the vector are created on the heap.
At first sight, there're two problems with your code. The first one is not critical, but anyway: The comparison
if (m_vecItems.size() > m_vecItems.capacity())
is always
false
, so there's no point in checking it. By definition, the size of a vector canot be larger than its capacity. As forif (m_vecItems.size() == m_vecItems.capacity())
it is not really necessary (vectors grow as necessary automatically), but it can improve performance, so no problem about it. The real problem (I guess) is that
sort
expects a comparison predicate that has less-than semantics, i.e. it expects it to returntrue
is the first argument if less than the second, andfalse
otherwise. YoursortCallback
has (<0,0,>0) semantics: change it to what I've indicated and things will probably start to work OK. Good luck. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
At first sight, there're two problems with your code. The first one is not critical, but anyway: The comparison
if (m_vecItems.size() > m_vecItems.capacity())
is always
false
, so there's no point in checking it. By definition, the size of a vector canot be larger than its capacity. As forif (m_vecItems.size() == m_vecItems.capacity())
it is not really necessary (vectors grow as necessary automatically), but it can improve performance, so no problem about it. The real problem (I guess) is that
sort
expects a comparison predicate that has less-than semantics, i.e. it expects it to returntrue
is the first argument if less than the second, andfalse
otherwise. YoursortCallback
has (<0,0,>0) semantics: change it to what I've indicated and things will probably start to work OK. Good luck. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo