Results 1 to 3 of 3

Thread: QMutableListIterator remove() crashing on Windows

  1. #1
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QMutableListIterator remove() crashing on Windows

    Compiled with Visual Studio 2008, an implementation iterating thought a QModelIndexList (obtained using QItemSelectionModel::selectedRows() ) using QMutableListIterator causes a crash when calling QMutableListIterator::remove(). This only occurs on Windows, using GCC on Linux (haven't tested MinGW on Windows) causes no crash. The error when it crashes on Windows is a genereal heap corruption error, and the debugger crashes exactly on that line. The list itself is valid, and this occurs right after program startup, so I am 99% certain that the heap isn't becoming corrupted earlier on (No delete operations have been done whatsoever on the list before this, and it deisplays perfectly in the model without crashing, which you would expect it to do if there had been any ehap corruption before this).
    Is this a (known) bug in Qt or maybe in the MSVC compiler? Has anyone encountered this before?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QMutableListIterator remove() crashing on Windows

    Can we see the exact code used to manipulate the container using the iterator?

  3. #3
    Join Date
    Aug 2006
    Posts
    163
    Thanks
    12
    Thanked 5 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QMutableListIterator remove() crashing on Windows

    Yes, of course:

    Qt Code:
    1. QList< File* > BaseModel::cleanSelection( QModelIndexList &selection ) const
    2. {
    3. /* We want to filter the index list here, since we cannot allow a selection to contain both
    4.   root items and children of those root items. Here we traverse the list, filtering out any
    5.   children who's parents are also in the list */
    6.  
    7. QMutableListIterator< QModelIndex > it( selection );
    8. QList< File* > files;
    9.  
    10. while( it.hasNext() ){
    11. QModelIndex idx = it.next();
    12. BaseType *base = static_cast< BaseType* >( idx.internalPointer() );
    13.  
    14. if( base->type() == "File" ){
    15. File *file = dynamic_cast< File* >( base );
    16.  
    17. if( file ){
    18. //If the current files parent is also in the list, then we don't want to process it
    19. if( selection.indexOf( index( downloadqueue->indexOf( file->parent() ), 0 ) ) != -1 ){
    20. files.append( file );
    21. it.remove();
    22. }
    23. }
    24. }
    25. }
    26.  
    27. return files;
    28. }
    To copy to clipboard, switch view to plain text mode 

    It crashes on line 21, it.remove().
    This code is being called from here:

    Qt Code:
    1. void KNewzModel::moveToTop()
    2. {
    3. QModelIndexList selection = view->selectionModel()->selectedRows();
    4.  
    5. if( selection.size() < 1 )
    6. return;
    7.  
    8. QList< File* > files = cleanSelection( selection );
    9. QMutexLocker lock( &downloadqueue->mutex() );
    10. QModelIndex rootIdx = index( 0, 0 );
    11. QModelIndex childIdx = index( 0, 0, rootIdx );
    12.  
    13. foreach( const QModelIndex &idx, selection ){
    14. BaseType *base = static_cast< BaseType* >( idx.internalPointer() );
    15.  
    16. if( base->type() == "NzbFile" ){
    17. NzbFile *nzbFile = dynamic_cast< NzbFile* >( base );
    18.  
    19. if( !nzbFile )
    20. break;
    21.  
    22. //No need to move the first item to the top, it's there already
    23. if( nzbFile == downloadqueue->first() )
    24. continue;
    25.  
    26. int row = downloadqueue->indexOf( nzbFile );
    27. Q_ASSERT( row >= 0 && row < downloadqueue->size() );
    28. QModelIndex idx = index( row, 0 );
    29. bool expanded = view->isExpanded( idx );
    30. beginRemoveRows( QModelIndex(), row, row );
    31. nzbFile = downloadqueue->takeAt( row );
    32. int rows = nzbFile->size();
    33. endRemoveRows();
    34. row = rootIdx.row();
    35. beginInsertRows( QModelIndex(), row, row );
    36. downloadqueue->insert( row, nzbFile );
    37. endInsertRows();
    38. QModelIndex newIdx = index( row, 0 );
    39. emit dataChanged( newIdx, index( rows, columnCount(), newIdx ) );
    40.  
    41. if( files.size() > 0 ){
    42. File *firstChild = nzbFile->first();
    43.  
    44. /* Check if any children were selected. We can't just ignore them now,
    45.   because this action can legally operate on both children and their top-level
    46.   parent simultaneously */
    47. QMutableListIterator< File* > it( files );
    48.  
    49. while( it.hasNext() ){
    50. File *file = it.next();
    51.  
    52. if( file->parent() == nzbFile ){
    53. it.remove();
    54. int row = nzbFile->indexOf( file );
    55.  
    56. if( row >= 0 && row < nzbFile->size() ){
    57. beginRemoveRows( newIdx, row, row );
    58. file = nzbFile->takeAt( row );
    59. endRemoveRows();
    60. row = nzbFile->indexOf( firstChild );
    61.  
    62. if( row < 0 )
    63. row = 0;
    64.  
    65. beginInsertRows( newIdx, row, row );
    66. nzbFile->insert( row, file );
    67. endInsertRows();
    68. emit dataChanged( index( row, 0, newIdx ), index( row, columnCount(), newIdx ) );
    69. }
    70. }
    71. }
    72. }
    73.  
    74. if( expanded )
    75. view->setExpanded( newIdx, true );
    76. }else{
    77. File *file = dynamic_cast< File* >( base );
    78. NzbFile *nzbFile = file->parent();
    79. int row = nzbFile->indexOf( file );
    80.  
    81. /* We want row > 0 here because we don't need to move the first child
    82.   to the top since it's already there */
    83. if( row > 0 && row < nzbFile->size() ){
    84. QModelIndex parentIdx = index( downloadqueue->indexOf( nzbFile ), 0 );
    85. Q_ASSERT( parentIdx.isValid() );
    86. beginRemoveRows( parentIdx, row, row );
    87. file = nzbFile->takeAt( row );
    88. endRemoveRows();
    89. beginInsertRows( parentIdx, 0, 0 );
    90. nzbFile->prepend( file );
    91. endInsertRows();
    92. emit dataChanged( index( 0, 0, parentIdx ), index( 0, columnCount(), parentIdx ) );
    93. }
    94. }
    95.  
    96. }
    97.  
    98. view->selectionModel()->clearSelection();
    99. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. QPageSetupDialog is crashing always
    By senthilsp in forum Qt Programming
    Replies: 1
    Last Post: 29th November 2007, 10:21
  2. Windows not appearing in XP.
    By beardybloke in forum Qt Programming
    Replies: 7
    Last Post: 24th October 2007, 17:32
  3. Printing problem in windows
    By joseph in forum Qt Programming
    Replies: 6
    Last Post: 12th July 2007, 08:04
  4. converting unix exe to windows binary
    By deekayt in forum General Programming
    Replies: 2
    Last Post: 17th September 2006, 01:00
  5. MDI windows without QWorkspace
    By Big Duck in forum Newbie
    Replies: 2
    Last Post: 16th June 2006, 17:15

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.