segfault in qlistwidget



  • im inheriting QListWidget to MyListWidget
    why do i keep getting segfault here?
    void MyListWidget::keyPressEvent(QKeyEvent *event)
    {
    if ( event->key() == Qt::Key_Delete )
    {

        for ( QList<QListWidgetItem*>::iterator iter = selectedItems().begin(); iter != selectedItems().end(); iter++ )
        {
            qDebug() << (*iter)->text();
        }
      
    }
    

    }

    but when i do this, it works fine
    void MyListWidget::keyPressEvent(QKeyEvent event)
    {
    if ( event->key() == Qt::Key_Delete )
    {
    QList<QListWidgetItem
    > sItems = selectedItems();
    for ( QList<QListWidgetItem*>::iterator iter = sItems.begin(); iter != sItems.end(); iter++ )
    {
    qDebug() << (*iter)->text();
    }

    }
    

    }


  • Moderators

    Where exactly does it crash? in the line with qDebug()?
    Try to debug and execute step by step.



  • @jsulm yea , in the debug() line, when the function is executed, segfault appears



  • This should segfault on the qDebug line most of the time.

    Your first version is using two different QList<QListWidgetItem*> arrays. The begin() and end() functions are from two different lists. The second version that works is iterating using a single list so the begin() and end() functions are both from the same list.

    I am sure the contents of either list is the same but the memory addresses are not.



  • @Rondog
    i dont get it, the first version is an iterator for the selectedItems();

    selectedItems() returns QList<QListWidgetItem *> from the documentation of QListWidget



  • It is not the iterator that is the problem. From your example:

    for ( QList<QListWidgetItem*>::iterator iter = selectedItems().begin(); iter != selectedItems().end(); iter++ )
    {
        qDebug() << (*iter)->text();
    }
    

    The functions 'selectedItems().begin()' and 'selectedItems().end()' are the problem. Each time you call 'selectedItems()' a copy of QList<QListWidgetItem*> array is returned. Since you call it twice you have two different copies. The contents of the list may be the same but they are two different lists.

    Consider this:

    QString input_text("    some  text for    input ");
    QString text = input_text.simplified().trimmed().mid(1);
    

    In order to have the second line work a QString is constructed (and destroyed) for each step as a copy constructor. The QString member 'simplfied()' returns an unnamed instance of a new copy of QString after performing whatever 'simplfied()' does. The member 'trimmed()' is then called from this new QString creating another unnamed instance which finally calls member 'mid(1)'. The final variable 'text' is assigned from the last member function of the unnamed instance of QString. If the last member was '.toInt()' it would return an integer instead (which won't compile unless the assigned variable is changed to an integer (or acceptes an integer as a constructor)).

    The output from the above example is "ome text for input" if you are curious.

    The member function QListWidget::selectedItems(void) might looks something like this:

    QList<QListWidgetItem*> QListWidget::selectedItems(void) const
    {
    	QList<QListWidgetItem*> list;
    	list.push_back(<figure out what is selected>);
    	return list;
    }
    
    

    You end up calling this function twice and therefore you have two different lists as you would expect (returned values from the same function will each have a unique instance). Your loop starts on the beginning of the first list and ends on the last item of the second list. It is very likely they are not sitting next to each other in memory so after the first list is traversed you are running over unknown memory (which is where your segfault comes from).

    You need to be careful about copy constructors (when they are created). For example, your 'for' loop uses the postfix operator 'iter++'. For simple variables (integers) this is not a problem but if you have a complex iterator calling the postfix version will be expensive at it creates a copy. A better form is to use the prefix operator '++iter' as no copy is created.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.