0
votes

in this program, items (markers) are added to a QListWidget calles ui->lwMarkers. These items can also be removed again by pressing the "Remove button" which calls the following function

void Form::on_pbRemoveMarker_clicked()
{
    if (ui->lwMarkers->currentRow() < 0) return;

    delete ui->lwMarkers->takeItem(ui->lwMarkers->currentRow());
}

Inside the function, the first line is to make sure an item (marker) is actually selected. The second line is (at least, I hope) to delete the selected item.

Adding and removing: all goes well, unless when you want to remove next-to-last item. Then it crashes, unfortunately. I do not see why.

Can anyone shed a light on this issue?

If it can help: the full code is from the qt-google-maps project: https://code.google.com/p/qt-google-maps/ . This project uses the Google Maps API v2, I altered the code to use v3.

The question that I ask, is a particular behaviour of their code, and I simply don't see the reason of the crash. Any help?

The crash always happens just before the delete, I believe it is because of the takeItem and the error I get is as follows: ASSERT failure in QList::operator[]: "index out of range", file ../../QtSDK/Desktop/Qt/473/gcc/include/QtCore/qlist.h, line 464

1
Can you confirm that the ui->lwMarkers->currentRow() is not returning from 1 to N, where N is the number of rows? If that's the case you have to subtract one from the currentRow() to use on the take item.Felipe Tonello
( I made a mistake in my previous comment and deleted it, here is the correct information: ) qt-project.org/doc/qt-4.8/qlistwidget.html#currentRow-prop : actually, the currentRow() returns 0 to N-1 when a row is active/selected . When no row is active/selected, it returns -1 (therefore the if-test)Wim

1 Answers

0
votes

Could it be that takeItem is the evildoer? According to the class reference , it removes the item from the QListWidget and returns it. It also mentions:

Items removed from a list widget will not be managed by Qt, and will need to be deleted manually.

This is why, to me, the original code seems correct, you remove the item from the list widget and delete it afterwards. Still, it gives the above mentioned error when trying to remove the next-to-last item.

I suggest to use the item() function instead, and delete it accordingly:

void Form::on_pbRemoveMarker_clicked()
{
    if (ui->lwMarkers->currentRow() < 0) return;

    delete ui->lwMarkers->item(ui->lwMarkers->currentRow());
}

The frontend of the program is now working as expected, but do I leave memory leaks this way?

Any other problem you might see?