Discussion:
wxListCtrl crashes on sort when wx is compiled with --enable-stl
s1s0
2012-06-10 13:29:23 UTC
Permalink
Hi,
A code which is using wxListCtrl and works happily for years on a number of
platforms is crashing consistently if wx is compiled with --enagle-stl
option. The same code works fine if wx is compiled without the option above.
I come across the problem recently when I compiled my code on latest SuSE.
Later I recreated the issue on Fedora with the latest from both 2.8 and 2.9
branches.
The code is using callback for the sorting. Interestingly, the callback
function is called with item IDs which can not be found by FindItem.
Subsequently the wx code crashes.

I'll appreciate some help.

Regards
Svilen

(Example code of the sorting callback function below)

int wxCALLBACK wxListCompareFunction(long item1, long item2, long sortData)
{
wxListItem li1, li2;
long lItem = wxNOT_FOUND;
li1.SetMask(wxLIST_MASK_TEXT);
li1.SetColumn(1);
lItem = CmdList->FindItem(-1, item1);
if (wxNOT_FOUND == lItem)
return -1;
li1.SetId(lItem);
CmdList->GetItem(li1);
li2.SetMask(wxLIST_MASK_TEXT);
li2.SetColumn(1);
lItem = CmdList->FindItem(-1, item2);
if (wxNOT_FOUND == lItem)
return 1;
li2.SetId(lItem);
CmdList->GetItem(li2);
wxString s1 = li1.GetText();
wxString s2 = li2.GetText();
return s1.CompareTo(s2.c_str());
}
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
David Connet
2012-06-10 14:09:46 UTC
Permalink
Post by s1s0
Hi,
A code which is using wxListCtrl and works happily for years on a number
of platforms is crashing consistently if wx is compiled with
--enagle-stl option. The same code works fine if wx is compiled without
the option above.
I come across the problem recently when I compiled my code on latest
SuSE. Later I recreated the issue on Fedora with the latest from both
2.8 and 2.9 branches.
The code is using callback for the sorting. Interestingly, the callback
function is called with item IDs which can not be found by FindItem.
Subsequently the wx code crashes.
That's because item1/item2 are not the item IDs. They are the client
data. And if you are compiling on 64bit, then this is a problem as a
pointer won't fit in a long [on msw at least] (wx2.9 fixes this - the
callback changed to using wxIntPtr). (I worked around this in 2.8 by
using ints in the client data which are basically indices into an array
I keep.)

Dave
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
s1s0
2012-06-10 15:00:27 UTC
Permalink
Well,
They are actually both in my case (see the code - itemID and user data)
void console::TELLFuncList::addFunc(wxString name, void* arguments)
{
....
wxListItem row;
row.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_TEXT);
row.SetId(GetItemCount());
row.SetData(GetItemCount());
....
and as far as I can see both wx functions (SetId/SetData) take long.
It actually crashes with wx 2.9.3 as well. Besides I'm talking here about
Fedora 64 bit- haven't tried it on Windows, but it looks like it's going to
crash there as well (as you say)
If I read you properly - it is an issue in wx and at the moment the
workaround is to use virtual control - i.e. to manage the items data by
the user's code? Or eventually avoid using --enable-stl?

Svilen
Post by David Connet
That's because item1/item2 are not the item IDs. They are the client
data. And if you are compiling on 64bit, then this is a problem as a
pointer won't fit in a long [on msw at least] (wx2.9 fixes this - the
callback changed to using wxIntPtr). (I worked around this in 2.8 by
using ints in the client data which are basically indices into an array
I keep.)
Dave
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Vadim Zeitlin
2012-06-10 18:11:54 UTC
Permalink
On Sun, 10 Jun 2012 06:29:23 -0700 (PDT) s1s0 wrote:

s> A code which is using wxListCtrl and works happily for years on a number of
s> platforms is crashing consistently if wx is compiled with --enagle-stl
s> option.

As mentioned on http://www.wxwidgets.org/support/mlhowto.htm#crashes,
please provide stack traces for the crashes as it's not clear at all from
your post where does it crash exactly.

s> The code is using callback for the sorting. Interestingly, the callback
s> function is called with item IDs which can not be found by FindItem.

Another reply already stated that you get item data and not item IDs in
the callback so, again, it's not clear why do you expect treating them as
item indices to work.

s> (Example code of the sorting callback function below)

Also please try to reproduce the problem in the listctrl sample. If you
can make a patch (see http://trac.wxwidgets.org/wiki/HowToSubmitPatches)
showing it there, it would greatly increase the chance of fixing this bug.

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
s1s0
2012-06-11 23:43:20 UTC
Permalink
OK, I just though that it is a known issue (as it appears to be :) ).
My confusion comes primarily from the fact that the code is working fine
without that option. You're both right - the trouble was that I'm treating
the function params as item IDs. The example wasn't crashing, but there is
not much there related to the sorting anyway (no data retrieval from the
control).

Correct me if I'm wrong, but for the reasonable number of items - it is
better to keep a copy of the data outside the wxListCtrl if you need to
sort the items reasonably quickly. The latter - provided that I have number
of columns and sorting criteria. As far as I can see - there is no quick
way to retrieve an item with certain user data?

As far as the crash is concerned - it was obviously produced by conflicting
results from the callback function.

Thanks for your help!
Svilen
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Vadim Zeitlin
2012-06-12 11:28:29 UTC
Permalink
On Mon, 11 Jun 2012 16:43:20 -0700 (PDT) s1s0 wrote:

s> Correct me if I'm wrong, but for the reasonable number of items - it is
s> better to keep a copy of the data outside the wxListCtrl if you need to
s> sort the items reasonably quickly.

Yes, it's better to use virtual wxListCtrl (i.e. with wxLC_VIRTUAL) style
for more than a couple of thousands of items.

s> As far as I can see - there is no quick way to retrieve an item with
s> certain user data?

No but with virtual control you don't need to do this because your user
data is already the pointer to the "real" item, i.e. all the information
about the item that you have is accessible via it. And for non virtual
control you can just do a linear search because it doesn't (or shouldn't)
have that many items anyhow.

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Christoph Vollmer
2014-03-27 16:31:30 UTC
Permalink
Sorry to bring this old topic back up but i have a similar problem and i
can't fix this on my own.
I am trying to sort a wxListView but it should be the same as an wxListCtrl
i guess.

my sort function looks like this:

int wxCALLBACK MyBotSortFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr
sortData)
{
wxListCtrl *List = (wxListCtrl *) sortData;
long index1 = List->FindItem(-1, item1);
long index2 = List->FindItem(-1, item2);
...
}

and the way i'm calling it looks like this:

for (long i=0; i<ListViewBots->GetItemCount();i++)
ListViewBots->SetItemData(i,i);

ListViewBots->SortItems(MyBotSortFunction,(wxIntPtr)ListViewBots);

Its working for most of my entries in the ListView but at some entries it
failes..
When the function gets called with item1 = 2 and item2 = 1
FindItem(-1,item1) returns -1

I'm using wxwidgets 3.0, its working on windows but it fails on linux.
Do you have any idea why?
The Listview contains only ~34 entries so it can't really be a problem with
the ItemData i guess (which seems to be long)

thanks in advance
Chris
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Vadim Zeitlin
2014-03-27 22:08:44 UTC
Permalink
On Thu, 27 Mar 2014 09:31:30 -0700 (PDT) Christoph Vollmer wrote:

CV> I am trying to sort a wxListView but it should be the same as an wxListCtrl
CV> i guess.

Yes, it is.

CV> my sort function looks like this:
CV>
CV> int wxCALLBACK MyBotSortFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr
CV> sortData)
CV> {
CV> wxListCtrl *List = (wxListCtrl *) sortData;
CV> long index1 = List->FindItem(-1, item1);
CV> long index2 = List->FindItem(-1, item2);
CV> ...
CV> }

I guess even the big "NOT" in SortItems() documentation isn't noticeable
enough to save people from this -- I agree, completely unexpected --
callback convention. I'll try making it bold, too. But in the meanwhile
notice:

The parameter @e item1 is the client data associated with the first item (NOT the index).
The parameter @e item2 is the client data associated with the second item (NOT the index).
The parameter @e data is the value passed to SortItems() itself.

I.e. you're using the parameters incorrectly.

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Christoph Vollmer
2014-03-27 22:45:30 UTC
Permalink
Post by Vadim Zeitlin
I guess even the big "NOT" in SortItems() documentation isn't noticeable
enough to save people from this -- I agree, completely unexpected --
callback convention. I'll try making it bold, too. But in the meanwhile
first item (NOT the index).
second item (NOT the index).
I.e. you're using the parameters incorrectly.
Hey,

thanks for your fast reply.
From my understanding i'm doing it this way right now:

Before searching i set the item data of each row to its index
for (long i=0; i<ListViewBots->GetItemCount();i++)
ListViewBots->SetItemData(i,i);

and while searching i use this data to search for the real index of the
row, use the index to get the Text and then do my comparisons...
long index1 = List->FindItem(-1, item1);
i thought FindItem returns the index of the row with the data set searlier
with SetItemData...

Maybe i'm completely wrong here but thats the way i understood the way it
is working ...
If the client data you are talking about (item1 & item2) are not the data
is set earlier with
SetItemData(i,i);
then what is this data?

On i side note:
i did print my Listview in the beginning of each SortFunction run and this
is what i found to be my problem (i removed lines that were not of
interest). The Listview is sorted by "name"

Entries: 34 item1: 2 item2: 17
i: 0 data: 1 name: Balthesaur status: Idle
i: 1 data: 17 name: PAC-Attack status: Idle
i: 2 data: 2 name: bulldogs status: Idle
i: 3 data: 15 name: oneup status: Idle

Entries: 34 item1: 2 item2: 1
i: 0 data: 1 name: Balthesaur status: Idle
i: 1 data: 17 name: PAC-Attack status: Idle
i: 2 data: 17 name: PAC-Attack status: Idle
i: 3 data: 15 name: oneup status: Idle

In the first run index 1 and index 2 are checked and switched around
(PAC-Attack is greater than bulldogs).
As you can see in the second run they haven't been switched around, index 2
has been overwritten by index 1.

Even if i'm using the parameters incorrectly, how can s.th. like this
happen?
And this is where my sorting fails because in the 2nd run the entry with
data 2 can't be found anymore...

Sorry if this completely stupid but i searched and searched but i haven't
found one single easy example for sorting ....

- Chris
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Vadim Zeitlin
2014-03-28 12:47:56 UTC
Permalink
On Thu, 27 Mar 2014 15:45:30 -0700 (PDT) Christoph Vollmer wrote:

CV> Before searching i set the item data of each row to its index
CV> for (long i=0; i<ListViewBots->GetItemCount();i++)
CV> ListViewBots->SetItemData(i,i);

Ah, I didn't know this. Then your code indeed looks like it ought to work.

CV> and while searching i use this data to search for the real index of the
CV> row, use the index to get the Text and then do my comparisons...
CV> long index1 = List->FindItem(-1, item1);
CV> i thought FindItem returns the index of the row with the data set searlier
CV> with SetItemData...

Yes, this overload of it does.

CV> On i side note:
CV> i did print my Listview in the beginning of each SortFunction run and this
CV> is what i found to be my problem (i removed lines that were not of
CV> interest). The Listview is sorted by "name"
CV>
CV> Entries: 34 item1: 2 item2: 17
CV> i: 0 data: 1 name: Balthesaur status: Idle
CV> i: 1 data: 17 name: PAC-Attack status: Idle
CV> i: 2 data: 2 name: bulldogs status: Idle
CV> i: 3 data: 15 name: oneup status: Idle

Where do the values 15 and 17 for the data come from if you set the data
to the index?

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Loading...