PDA

View Full Version : attempting to access QStandardItemModel causes seg fault in some cases



briankeeney
6th February 2013, 04:03
Hi All,

I'm having a bizarre problem with QStandardItemModel. I've implemented a pointer to a model in my mainwindow class. In a setup function in that class I create a model and point that model to the member pointer in the class. In another function, I sucessfully set it up. In still another, I successfully manipulate it. In a third, it always causes a seg fault. So clearly I'm doing something wrong. I would have to reimplement a ton of code to make a simple project, so I'm hoping first with the below snippets that it will be obvious what I'm doing wrong. Any ideas? It's like it's a scope problem, but it's all in one class.

Thanks,
Brian




In Mainwindow.h, as part of class:

QStandardItemModel * archive_model;





In mainwindow.cpp:

setup(){
archive_model = new QStandardItemModel(this);
btx_api->getRuns(*archive_model);

get_request(){
foo = archive_model->item(ind.row(),0)->text();//foo has correct value "1"
}

other_request(){
foo = archive_model->item(ind.row(),0)->text();//causes seg fault.
}

Lykurg
6th February 2013, 07:49
Maybe other_request is called before you have created the model? Check if archive_model is valid when calling other_request and also what value have ind.row()?

From the snippet I see no error.

briankeeney
6th February 2013, 18:06
Hi Lykurg,

Good ideas-- Thanks! Unfortunately, using
foo = archive_model->item(0,0)->text(); also causes a seg fault. I've checked that I'm not calling other_request() before the model is populated. Any other ideas? Is this a textbook way of using models-- that is, place the pointer in the class, create the model in a method of the class, access it in other methods using the pointer? I'm a newbie...

Thanks,
Brian

d_stranz
6th February 2013, 18:34
I'm a newbie...

One of the things that most newbies learn the hard way is to *never* assume that a pointer returned from a function call is valid. Blindly trusting that archive_model->item( 0, 0 ) will *always* return a valid pointer will lead you down the path to segmentation faults. Or assuming that ind.row() always returns a valid row index, or that "ind" itself is valid, or any of multiple assumptions you are making in your code.

One of the characteristics of Qt's Model/View architecture is that invalid model indexes are a standard return value used to indicate that something being requested doesn't exist (like a parent of a given index, or an index at a given row and column). If you simply assume you will always get a valid index, then you'll end up where you are now.

Check pointers to see that they are non-NULL, check all model indexes for validity (QModelIndex::isValid()), check everything that could give rise to an error even if you *know* there can't be anything wrong :-).

If your archive_model pointer has been created in the constructor somewhere, you can probably safely assume it is valid (unless it could be deleted and left dangling somewhere else in your code, which leads to a seg fault), but if it is created somewhere else, then you need to initialize it to zero in the constructor (otherwise it contains garbage and points to a seg fault) and check it before you try to use it. Then you need to check that your index is valid before you try to access something in your model using it (otherwise a seg fault), then you need to check that the pointer returned from your model is valid (another seg fault opportunity), and then if the call to text() also returns a pointer, you need to check that too before using it (ditto).

Either insert these error checks into your code, or use asserts() (which do nothing in release mode), or use the debugger to find out where and why the seg fault occurs.

briankeeney
8th February 2013, 23:19
Thanks! I think you're right on target with that. It certainly ended up being the problem in this case-- I was using the index from one model to call another, so I ran off the end of the model and was rightly smacked down for it.

d_stranz
12th February 2013, 22:35
Hmmm, I don't think that QModelIndex instances can be "shared" among models - an index into a model is specific to that model, and can't be used to refer to an item at the same location in a different model, if that's what you mean you are trying to do. You can extract the row and column numbers from the index and use them to retrieve the corresponding index from the other model, but then you still need to check that both the source and target indexes are valid.