PDA

View Full Version : Crash: Heap corruption due to selectedRows()



Ankitha Varsha
10th November 2008, 17:40
Hi,

I have a very simple thing implemented.

//Connect statement something like this...

connect( &contextMenu, SIGNAL( aboutToShow() ), q, SLOT( createContextMenu() ) );


void ClientsGroupsView::createContextMenu()
{
if( selectionModel() == 0 )
return;

const QModelIndexList rows = selectionModel()->selectedRows();

// some other code to show the contents of context menu

}

It is basically a tree view. When the function createContextMenu() returns ( at } ), it is causing crash stating that the crash is due to some heap corruption.

Strangely, If I remove the line which fetches the selectedRows(), the function return does not cause any crash!. I just commented all the lines which make use of "rows" list. It still causes the crash. I do not understand this. I mean, I am not even making use of rows list ( I have to make use of it eventually though), just fetching selectionModel()->selectedRows(); causes the crash at the function return.

Here is the call stack:

ntdll.dll!77f22ea8()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!77f90c9a()
ntdll.dll!77f64bdf()
ntdll.dll!77ef894a()
> QtCored4.dll!QBasicAtomicPointer<QInternal_CallBackTable>::operator!() Line 127
QtCored4.dll!global_callback_table() Line 2633 + 0x117 bytes C++


Any kind of information will be very helpful.

Thank you,
Ankitha Varsha

jacek
10th November 2008, 22:15
Do you set selection model somewhere in your code?

Ankitha Varsha
11th November 2008, 04:36
Not really, There will be a default selection model right?

caduel
11th November 2008, 07:10
yes, after you call setModel(), there will be a default selection model.

Ankitha Varsha
11th November 2008, 10:45
Then I am wondering what could be the problem .
Why would the function return lead to crash if I use selectedRows() method on the selection model. I made sure that there are not illegal statements on the usage of the return value of selectedRows(). Some light please :(

jacek
11th November 2008, 22:17
Probably selectedRows() returns invalid pointer. Does it crash if you only invoke selectedRows() (without dereferencing the pointer)? How do you set the model?

Yeter
30th January 2009, 08:51
Probably selectedRows() returns invalid pointer. Does it crash if you only invoke selectedRows() (without dereferencing the pointer)? How do you set the model?

Hi,

I have the same problem.

It does not crash when invoking selectedRows() but when the return value of selectedRows() leaves scope.



QItemSelectionModel *model = myQTableView->selectionModel();

if (model)
{
QModelIndexList selectedRows = model->selectedRows();

if (selectedRows.count() == 1)
{
int selRowIdx = selectedRows[0].row() ;
...
}
} <---- here is the crash


The call stack is as follows:



msvcr90d.dll!_CrtIsValidHeapPointer(const void * pUserData=0x0175d5c0) Line 2103 C++
msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x0175d5c0, int nBlockUse=1) Line 1317 + 0x9 bytes C++
msvcr90d.dll!_free_dbg(void * pUserData=0x0175d5c0, int nBlockUse=1) Line 1258 + 0xd bytes C++
msvcr90d.dll!operator delete(void * pUserData=0x0175d5c0) Line 54 + 0x10 bytes C++
MyApp.exe!QModelIndex::`scalar deleting destructor'() + 0x46 bytes C++
MyApp!QList<QModelIndex>::node_destruct(QList<QModelIndex>::Node * from=0x0175d7a4, QList<QModelIndex>::Node * to=0x0175d7a4) Line 340 + 0x3e bytes C++
MyApp!QList<QModelIndex>::free(QListData::Data * data=0x0175d790) Line 539 C++
MyApp!QList<QModelIndex>::~QList<QModelIndex>() Line 513 C++


Any help appreciated.

jacek
30th January 2009, 23:49
Does it crash if you comment out lines 7--11?

Yeter
2nd February 2009, 12:17
Does it crash if you comment out lines 7--11?

It also chrashes if I comment out the lines 7-11.

In the call stack you can see that the call of the destructor of QList is the problem.

QModelIndexList selectedRows = model->selectedRows();
creates the list and after leaving scope the destructor of this list tries to delete its items.

I think the problem is either that the item already has been delete or belongs to an other object.

I just copied the code from the Qt-Reference and I really don't know why it crashes resp. what I could do to make it work.

wysota
2nd February 2009, 15:14
Is your application multithreaded?

Yeter
3rd February 2009, 10:16
Is your application multithreaded?

No it is not

Here is an example:
test.h

#ifndef TEST_H_
#define TEST_H_

#include "types.h"

#include "Ui_test.h"


class tableView : public QDialog, protected Ui_Dialog
{
Q_OBJECT
public:
tableView(QWidget* parent = 0, Qt::WindowFlags flags = 0);

private slots:
void btn_testClick();
};

#endif // end of #ifndef TEST_H_

test.cpp

#include <QtGui/QMessageBox>
#include <QtGui/QStandardItemModel>
#include <QtGui/QItemSelectionModel>

#include "test.h"


tableView::tableView(QWidget* parent /* = 0 */, Qt::WindowFlags flags /* = 0 */)
: QDialog(parent, flags)
{
// create gui elements defined in the Ui_tableView class
setupUi(this);

connect(btn_test, SIGNAL(clicked()), this, SLOT(btn_testClick()) );

setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint);

if (!tv_test->model())
{
QStandardItemModel *newModel = new QStandardItemModel(0, 1);
tv_test->setModel(newModel);
}

QStandardItemModel *model = dynamic_cast<QStandardItemModel*>( tv_test->model() );

for (int idx = 1; idx < 11; idx++)
{
QStandardItem* item1 = new QStandardItem( QString("bla_%1").arg(idx) );
model->appendRow( item1 );
}

tv_test->setSelectionModel( new QItemSelectionModel( model ) );
}

void tableView::btn_testClick()
{
QItemSelectionModel *model = tv_test->selectionModel();

if (model)
{
QModelIndexList selectedRows = model->selectedRows();
}
}

Remark: The code just crashes if I select a row and push the Test button.

verma
13th October 2009, 12:57
Hi, please try following code it may solve the problem.
this code is to get selectedRows


QModelIndexList getSelectedRows()
{
QModelIndexList lstIndex ;

QItemSelection ranges = selectionModel()->selection();
for (int i = 0; i < ranges.count(); ++i)
{
QModelIndex parent = ranges.at(i).parent();
int right = ranges.at(i).model()->columnCount(parent) - 1;
if (ranges.at(i).left() == 0 && ranges.at(i).right() == right)
for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r)
lstIndex.append(ranges.at(i).model()->index(r, 0, parent));
}
return lstIndex;
}

andrey_s
21st October 2009, 00:30
I have the similar problem. Application crashes when it go out from the scope. I put a code sample below. Application will crash even if I remove strings 3 & 9-11. It crushes when trying to destruct QList object


void SpreadsheetView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
QItemSelectionModel* sModel = selectionModel();

QModelIndexList selectedItems;
selectedItems.append(sModel->selectedIndexes());


QModelIndex sel = deselected.indexes().value(0);
if(!deselected.indexes().empty() && selectedItems.count() > 0)
sModel->setCurrentIndex(selectedItems[selectedItems.count() - 1], QItemSelectionModel::Select);

QTreeView::selectionChanged(selected, deselected);

}

andrey_s
22nd October 2009, 02:29
I have the similar problem. Application crashes when it go out from the scope. I put a code sample below. Application will crash even if I remove strings 3 & 9-11. It crushes when trying to destruct QList object



I've found solution of my problem. There was 2 debug dll files included into the link section of project settings(VS2005) together with release libs.

I've spent 3(!) days to found out this. I so tired :crying:

euch
3rd February 2010, 08:14
I have the same broblem. Do yoy remember what you exactly did?

lunatike
3rd February 2010, 09:15
Advice: use "PageHeap" or "Application Verifier".
It will point out heap corruptions.

Cheers

Jothay
1st October 2010, 00:55
I'm having this same problem now as well. I've verified that my Debug build is using all debug DLL's and Release is using all release DLL's. However in both states I'm getting a crash from this the same way that the code snippit providers above do.

Is there something I can do to try and force this?

The Qt Devs say to check which DLLs you are using as well, which doesn't help me:
http://bugreports.qt.nokia.com/browse/QTBUG-7884