QGraphicsSceneFindItemBspTreeVisitor::visit crashes due to an obsolete PaintEvent after QGraphicsScene::removeItem

Hi,
I'm struggling since yesterday with this issue... I understand that the seg fault is coming because a paintEvent is trying to use an object that has been destroyed already.
Here is the backtrace, it doesn't help much...

Let me describe the situation:
I'm having Elements and Links between Elements. They have a a graphics representations in a scene. The issue seems to be that the LinkItem boundingRect is calculated like this:

It works fine until I'm arriving to the situation with only 2 Elements and my Link. In this case when I delete an Element, I'll also automatically delete the link.
so what is supposed to happen is
LinkItem::removeElement(elem);
delete elem; (that will delete the item when my link add an pointer to)
delete link;

Everything should be fine... cause the item shouldn't be in my array anymore and not used in the boundingRect, I can see with a trace that it has only one element but I don't know for what reason the crash seems to come from this...
If I comment out my boundingRect code, I don't have the segmentation fault...

Any idea why this is happening? How I could have more detail on the cause of the PaintEvent?

I'm running out of ideas, maybe to start using QSharedPointer instead of old school pointers for this particular graphic stuff, but it would be a significant effort on the project so I'd rather understand the problem especially if it is coming from somewhere else...

@SGaist
Hi,
no it's a single thread app.
I've managed to find out, what could be the cause, in my LinkItem::boundingRect, the item->centerPoint is call sceneBoundingRect()->center()
It seems that doing a call to the scene will cause some paint events that will crash later...
I don't understand why...
Normally the items are removed from the scene and from my set _allItems, so I shouldn't call it anymore...
I'm really struggling to understand the issue...
I'm thinking to do a simple basic application to try to reproduce the crash and post it here to show you this weird behaviour...
PS: I'm using QT 5.5.1

From what I view it, it's like a linked list with each item having links to the next item or if a doubly linked list, a link to the previous and next items.

For me, I think you can have it simpler. When an element is deleted, you should also delete the links. The element should have link properties and not as separate. So that when you delete the element, it will also delete the link (or links) with it.

Thus, in conclusion, an element has links and a polygon contains elements that has links.
To remove an element: first remove links, then remove the element then recalculate.

I hope this makes sense. My suggestion is focusing on the design hierarchy.

@josephdp
Hello Joseph,
thanks for your reply but in term of design this doesn't work.
My Link has a life in itself. I don't want to delete it when I remove one Element because it is still linking other Elements so still makes sense.
Even when there are no more Elements, I still want it in my scene cause when the user drag back an Elements in the scene they will connect to the Link.
Basically, my link is like a bus on which Equipments can be connected.
I'll try to finish tomorrow a basic example application of my use case and I'll share it so you can see the design and let me know what I'm doing wrong and also if you would do an easier/cleaner way.

Alright, I've done a little example that illustrate what my software is doing.
It's not so long but as there are several files and so you could just compile it and run it if you'd like, I've posted it on github.
You can find it here: https://github.com/mbruel/testSceneMgr/
The crash happens (not always but often) when I try to delete my LinkElement and so the LinkNMItem associated.
There are no issues when deleting the regular Elements...
Can you explain me what is the difference between both (Elements and Links) and why I'm getting this crash....
Also feel free to let me know if there is a better way to achieve what I'm trying to do.
Thanks in advance.

I've put a small record of the execution of the app on my laptop, you can find it here: https://sendvid.com/5fugajs8
The crash happens with a little delay... but nearly all the time when I delete the Link after having deleted all the Elements.

following this link: http://comments.gmane.org/gmane.comp.lib.qt.user/4719
I've noticed that at least on my example, not removing the QGraphicsItem from the scene before deleting it solve the issue.
I'm then checking the number of elements of my scene and it seems to be updated...
I don't really understand how the scene knows that an Item it is supposed to own has been deleted.
what is then the goal of QGraphicScene::removeItem... ?

Edit:

QGraphicsItem::~QGraphicsItem()
Destroys the QGraphicsItem and all its children. If this item is currently associated with a scene, the item will be removed from the scene before it is deleted.
Note: It is more efficient to remove the item from the QGraphicsScene before destroying the item.

So I get how it is removed from the scene... But still I don't get why it is crashing if I manually remove it from the scene before deletion.

@SGaist
Yes I do have sets of pointers on other objects but it is clear in term of ownership who will delete what.
My Elements have a sets of all the links they are in, and my Links one of all the Elements they are linking.
In their destructors, they remove themselves from the lists where they are referenced.

I don't think the problem comes from there... I'm thinking more and more that this could be a bug in QT GraphicScene stack where it is trying to use an object that has been removed and deleted...
I don't know maybe I'm doing something wrong...
any ideas?

well it's already quite a simple compilable program. You can find a zip of the project here https://github.com/mbruel/testSceneMgr/archive/master.zip
I don't know how I could reproduce it otherwise....
it's just a few classes with no more than 50 lines of code each.
With this project, the crash is reproducible every time on both Windows and Linux.
You just need to launch it, move the link, delete one Element, then delete the link and normally it crashed.

@josephdp
Hi Joseph,
In my project I do use intermediate GraphicMangers class between the Element and the Items.
But I still have some reference like on this exemple and it is made by design.
Here is the UML diagram of the example I made. http://postimg.org/image/3zso2igrd/
It is kind of clear:

Element owns a QGraphicsItem that is its graphical representation. (Element is in charge of the deletion of the QGraphicsItem)

LinkElement inherit from Element but is more complex and hold a set _elements of pointers that it is linking (no ownership). It has methods to add and remove elements from this set. Its inherited _item is more complex than for a regular Element, instead of using a ComplexItem it will be a LinkNMItem that inherit from LinkItem.

LinkItem inherit from QGraphicsItem and redefine the mouse events and also the paint. It has a set of pointer on the QGraphicsItems of the Elements that the LinkElement is linking. Also no ownership. There are methods to add/remove those items.

Anyway the crash doesn't come from those "circular" dependencies. It comes from the QGraphicsScene/QGraphicsView.
Doing some tests I can see the QGraphicsScene::removeItem works in the term that QGraphicScene::items().count() decreases BUT for some reason somewhere in QT stack, the item is still in use and the scene/view is not refreshed properly. I need to move another simplier item (one that has a boundingRect with fix size and/or that is not redefining the mouseMoveEvent) in order to have my item really removed from the scene.
I don't understand why... and it is a problem cause I'd like to destroy the item.

I then have a memory leak and we can see that the QGraphicsScene::removeItem fails to update the GraphicsView if I delete my link in second.
Cf this video: https://sendvid.com/nagutw1l
The link is still present on the scene until I move other Elements and then disappear at one point.
QT stack holds a pointer on it.
My crash is due to the fact I'm destroying the linkItem although QT still may use it, it even redraws it...

I need a way to make sure it is properly removed and won't be used anymore.

PS: I've changed a little bit the mouse event handlers to properly use or discard the events and it doesn't change the behaviour.

- QGraphicsScene::BspTreeIndex: A Binary Space Partitioning tree is applied. All QGraphicsScene's item location algorithms are of an order close to logarithmic complexity, by making use of binary search. Adding, moving and removing items is logarithmic. This approach is best for static scenes (i.e., scenes where most items do not move).
- QGraphicsScene::NoIndex: No index is applied. Item location is of linear complexity, as all items on the scene are searched. Adding, moving and removing items, however, is done in constant time. This approach is ideal for dynamic scenes, where many items are added, moved or removed continuously.

But I still find weird that QT keeps a pointer in the BSP indexing Tree on an QGraphicsItem removed from the scene... It's dangerous as the user should be free to delete that QGraphicsItem.
For me, the BSP tree should do all its last treatment before the end of QGraphicsScene::removeItem...

yes, I'm going to share this thread on the QT defect I mentioned before. It was open end of 2012, investigated last year but still not fixed.
it may help to provide them an easy way to reproduce the crash.