PDA

View Full Version : QMap deleting



morfis
12th June 2012, 02:00
I would like to have QMap as a part of class, so I add pointer to QMap in class private section, invoke a constructor of QMap in class constructor, and invoke destructor of QMap in class destructor. But if I invoke destructor of QMap, Segmentation fault is signaled. What do I wrong?


#include <QtCore/QCoreApplication>
#include <QMap>
#include <QMutableMapIterator>

class Segment
{
public:
Segment(quint32 sourceIP, quint32 destinationIP,
quint32 sequenceNumber,const unsigned char *segment)
{
qDebug("%s",Q_FUNC_INFO);
srcIP=sourceIP;
dstIP=destinationIP;
seqNo=sequenceNumber;
data=segment;
};
~Segment()
{
qDebug("%s",Q_FUNC_INFO);
};
quint32 srcIP;
quint32 dstIP;
quint32 seqNo;
private:
const unsigned char *data;
};

class Connection
{
public:
Connection(quint32 sourceIP, quint32 destinationIP)
{
qDebug("%s",Q_FUNC_INFO);
srcIP= sourceIP;
dstIP= destinationIP;
dstRCVMap= new QMap<quint32, Segment*>;
};
~Connection()
{
qDebug("%s",Q_FUNC_INFO);
QMutableMapIterator<quint32, Segment*> mapIter2(*dstRCVMap);
while (mapIter2.hasNext()){
Segment *segment= mapIter2.next().value();
delete segment;
mapIter2.remove();
};
delete dstRCVMap;//Problem
qDebug("END OF %s",Q_FUNC_INFO);
};
void append(Segment *segment)
{
qDebug("%s",Q_FUNC_INFO);
if (segment->srcIP==srcIP && segment->dstIP==dstIP)
dstRCVMap->insert(segment->seqNo, segment);
else
delete segment;
};
private:
quint32 srcIP;
quint32 dstIP;
QMap<quint32, Segment*> *dstRCVMap;
};

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
quint32 fakeIP1=123;
quint32 fakeIP2=456;
Connection con(fakeIP1,fakeIP2);
const unsigned char rawSegment[20]={0};
quint32 fakeSeqNo=1;
con.append(new Segment(fakeIP1,fakeIP2,fakeSeqNo,rawSegment));
// return a.exec();
}

mentalmushroom
12th June 2012, 07:19
On map destruction all iterators become invalid. In your code, being invalid, iterator is accessed again (released) when exiting from the destructor (iterator is allocated on the stack). This causes the issue. Allocate both map and iterator on the stack or both on the heap.

ChrisW67
12th June 2012, 07:38
The problem comes because the mutable iterator is holding a pointer or reference to the map. You delete the map and then, as the iterator destructor runs it crashes. You have two options:

Use a const iterator and do not remove the entries after deleting the segments. There's little point removing them at this point anyway: the map destructor will soon do it.
Use qDeleteAll(*dstRCVMap), which has the same effect as option 1.
Wrap the QMutableMapIterator loop in an anonymous block to make sure the iterator is destroyed (by leaving scope) before the map.

Ok, that's three options, but the third is ugly for most definitions of ugly.