Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 6

Qt-interest Archive, May 2004
QMap and QPopupMenu problem


Message 1 in thread

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi, i have a problem (what a surprise!) and the following scenario:

Class A own an instance of class B
Class A performs some operations and build a QMap<QString,int> then it passes 
the pointer of the built QMap to class B.
Class B opens a widget and draws something on a QCanvas.
Now the problem...

Class B has a method that traverses the QMap and draws items on the canvas 
basing on the contents of QMap's data(). 
If i invoke this method within the code to be executed normally (i.e. at end 
of constructor) everything is fine; but if i bind this slot to a QPopupMenu 
entry then the program segfaults whenever i attempt any kind of access to 
QMap internals!

bt showed that the error occurs in QString::operator =

i have no idea of what is going on...
anyone?

thanks a lot
- -- 
Francesco Lamonica: f DOT lamonica AT tin DOT it

PGP Fingerprint: 5870 92BA 8DFF 1ACF DE2E  B94D 46EC 5505 7C64 4EF1
Favourite quote: There's no spoon
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFAqlm+RuxVBXxkTvERAo6JAJ4jbcQbQRiz2lgagSoKY/jvQQsPSgCfekSj
+OqYqqxCeDkwBpUSuXV39bU=
=rxrr
-----END PGP SIGNATURE-----


Message 2 in thread

On May 18, 2004 12:45 pm, Francesco Lamonica wrote:
> Hi, i have a problem (what a surprise!) and the following scenario:
>
> Class A own an instance of class B
> Class A performs some operations and build a QMap<QString,int> then it
> passes the pointer of the built QMap to class B.
> Class B opens a widget and draws something on a QCanvas.
> Now the problem...
>
> Class B has a method that traverses the QMap and draws items on the canvas
> basing on the contents of QMap's data().
> If i invoke this method within the code to be executed normally (i.e. at
> end of constructor) everything is fine; but if i bind this slot to a
> QPopupMenu entry then the program segfaults whenever i attempt any kind of
> access to QMap internals!
>
> bt showed that the error occurs in QString::operator =

QMap is value-based rather than pointer-based and so should not really be able 
to cause the problem you are reporting.  Are you sure you have no memory 
leaks or pointer problems anywhere else in your code?  i.e. have you run it 
through something like valgrind or purify?

Try using the STL map type.  There's also debugging versions of the STL 
available from STLport which may help you out.

-- 
 [ signature omitted ] 

Message 3 in thread

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tuesday 18 May 2004 21:23, Chris Thompson wrote:
> On May 18, 2004 12:45 pm, Francesco Lamonica wrote:

> QMap is value-based rather than pointer-based and so should not really be
> able to cause the problem you are reporting.  Are you sure you have no

that was exactly my thought

> memory leaks or pointer problems anywhere else in your code?  i.e. have you
> run it through something like valgrind or purify?

yeah i used valgrind, there are some leaks which i was aware of (and must find 
some time to fix) but they are not related to my problem (i kept a watchful 
eye on the memory footprint and there is plenty of free memory when segfault 
happens)

Also, why should a leak affect QString::operator = ?

moreover, if there is a leak in my code... why should this make the segfault 
routinely happen when the code is executed from the popupmenu and _never_ 
ever when it is called within the code??? i cant see any logical difference 
in all this...

here follows the backtrace

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 16384 (LWP 17842)]
0x40709582 in QString::operator=(QString const&) ()
   from /usr/local/qt/lib/libqt-mt.so.3
Current language:  auto; currently c

#0  0x40709582 in QString::operator=(QString const&) ()
   from /usr/local/qt/lib/libqt-mt.so.3
#1  0x0805533e in QMapNode (this=0x84c4b80, _n=@0x72455100) at qmap.h:87
#2  0x08054fc4 in QMapPrivate<QString, int>::copy(QMapNode<QString, int>*) (
    this=0x84c50e8, p=0x72455100) at qmap.h:457
#3  0x08054f2a in QMapPrivate (this=0x84c50e8, _map=0x80d2454) at qmap.h:445
#4  0x08054ca4 in QMap<QString, int>::detachInternal() (this=0xbfffe7f0)
    at qmap.h:840
#5  0x08054c61 in QMap<QString, int>::detach() (this=0xbfffe7f0) at qmap.h:739
#6  0x0805454b in QMap<QString, int>::begin() (this=0xbfffe7f0) at qmap.h:660
#7  0x0807ccf3 in MatrixWidget::showPhases() (this=0x815b7b8)
    at matrix/matrixw.cpp:74
.
.
.
etc.

> Try using the STL map type.  There's also debugging versions of the STL
> available from STLport which may help you out.

uhm... my experience with STL is nearly non-existent so due to deadlines i 
think it would be non-practical :-)

btw this happens with qt 3.3.x (with x = 0,1,2)

- -- 
Francesco Lamonica: f DOT lamonica AT tin DOT it

PGP Fingerprint: 5870 92BA 8DFF 1ACF DE2E  B94D 46EC 5505 7C64 4EF1
Favourite quote: There's no spoon
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFAqmh9RuxVBXxkTvERAp08AJ48Qcrx94svc8NyW7ZJv01kbspO4QCgg1Ki
wQ4jpu3oK9VCT+0nSXbkoi0=
=ckB6
-----END PGP SIGNATURE-----


Message 4 in thread

On May 18, 2004 01:48 pm, Francesco Lamonica wrote:
>
> yeah i used valgrind, there are some leaks which i was aware of (and must
> find some time to fix) but they are not related to my problem (i kept a
> watchful eye on the memory footprint and there is plenty of free memory
> when segfault happens)
>
> Also, why should a leak affect QString::operator = ?

Memory leaks in their specific cases (i.e. allocated memory that is never 
freed) should not.  But the moment you access a pointer out-of-bounds (for 
example, char foo[2]; foo[2] = 'a';  or char foo[2];  foo[0] = 'a'; foo[1] = 
'b';  printf("%s", foo);), all bets are off.  It is legitimate for _anything_ 
to happen from then on, including having a bird fly out of the screen and 
attack the programmer (though thankfully nobody has implemented this yet).

> > Try using the STL map type.  There's also debugging versions of the STL
> > available from STLport which may help you out.
>
> uhm... my experience with STL is nearly non-existent so due to deadlines i
> think it would be non-practical :-)

While I'm sure this is true in general, you could probably just do the 
replacement in this one instance in just a couple of minutes.  That said, 
it's likely pointless unless you've fixed 100% of all your memory errors (at 
least, out-of-bounds errors, not pure memory leaks).

Alternatively, try creating a simple hello-world type application.  I'll bet 
you that you cannot duplicate the problem.  If you can, that clearly 
indicates a bug in Qt (or a problem with your compiler, or the use of your 
compiler).  Sometimes there's not much to do, though, but to go back to first 
principles.

-- 
 [ signature omitted ] 

Message 5 in thread

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tuesday 18 May 2004 21:57, Chris Thompson wrote:
> _anything_ to happen from then on, including having a bird fly out of the
> screen and attack the programmer (though thankfully nobody has implemented
> this yet).

ahahahahhahahah ;-) good heavens i already have migrains on my own... let 
alone a virtual bird beaking me! ;-)

as far as i can tell there are no 'out-of-bounds' probably (tho' one can never 
tell... :-) ) so i could quite expect my program to behave well :-)

> While I'm sure this is true in general, you could probably just do the
> replacement in this one instance in just a couple of minutes.  That said,
> it's likely pointless unless you've fixed 100% of all your memory errors
> (at least, out-of-bounds errors, not pure memory leaks).

i'll see if i manage to do that tomorrow

> Alternatively, try creating a simple hello-world type application.  I'll
> bet you that you cannot duplicate the problem.  If you can, that clearly
> indicates a bug in Qt (or a problem with your compiler, or the use of your
> compiler).  Sometimes there's not much to do, though, but to go back to
> first principles.


yeah well i forgot to tell, using gcc 3.3.3 compiled from sources on a 
slackware distro.

btw, if u want to look at some 'pseudo' code u can find it in my reply at 
caleb's email :-)

thanks again

- -- 
Francesco Lamonica: f DOT lamonica AT tin DOT it

PGP Fingerprint: 5870 92BA 8DFF 1ACF DE2E  B94D 46EC 5505 7C64 4EF1
Favourite quote: There's no spoon
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFAqqyPRuxVBXxkTvERAlUzAJ9aM2iU1GaO4p9FFyItgPjsMYnCJQCeKF8v
ccKp1/XddQ30+SBvJ+NzeUY=
=AQRc
-----END PGP SIGNATURE-----


Message 6 in thread

On Tuesday 18 May 2004 01:45 pm, Francesco Lamonica wrote:
> If i invoke this method within the code to be executed normally (i.e. at
> end of constructor) everything is fine; but if i bind this slot to a

Can you post the relevant code?  

Make sure in the constructor, you're not doing this:

class Object2
{
public:
  QMap *myobject;
}

Object2::Object2(QMap *o) {
   QMap *myobject = o;
}

As you have effectively created a local variable called myobject, and your 
class variable has been unitiailized;




> QPopupMenu entry then the program segfaults whenever i attempt any kind of
> access to QMap internals!
>
> bt showed that the error occurs in QString::operator =
>
> i have no idea of what is going on...
> anyone?
>
> thanks a lot
> - --
> Francesco Lamonica: f DOT lamonica AT tin DOT it
>
> PGP Fingerprint: 5870 92BA 8DFF 1ACF DE2E  B94D 46EC 5505 7C64 4EF1
> Favourite quote: There's no spoon
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.3 (GNU/Linux)
>
> iD8DBQFAqlm+RuxVBXxkTvERAo6JAJ4jbcQbQRiz2lgagSoKY/jvQQsPSgCfekSj
> +OqYqqxCeDkwBpUSuXV39bU=
> =rxrr
> -----END PGP SIGNATURE-----


Message 7 in thread

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tuesday 18 May 2004 21:55, Caleb Tennis wrote:
> On Tuesday 18 May 2004 01:45 pm, Francesco Lamonica wrote:
> > If i invoke this method within the code to be executed normally (i.e. at
> > end of constructor) everything is fine; but if i bind this slot to a
>
> Can you post the relevant code?

uhm.. it's not easy to take it out of context... i'll try to do my best

Main Object Code
- --------------------------

QMap<QString,int> mapPhaseLevel;
...
root.calculatePhaseLevels(&root,&mapPhaseLevel);

//debug phase level
qDebug("Numero di fasi identificate: %d",mapPhaseLevel.count());
//output is correct

QMapIterator<QString,int> it;
for( it=mapPhaseLevel.begin(); it!=mapPhaseLevel.end(); ++it )
  qDebug("key: %s - value: %d",it.key().ascii(),it.data());
//output is correct

qDebug("Map Phase Level Pointer: %p",&mapPhaseLevel);
hmw->setPhaseMap(&mapPhaseLevel);
hmw->drawHM(&root);


hmw class
- ----------------

header
{
Q_OBJECT
	private:
	 QCanvas *canvas;
	 QPopupMenu *mnuRClk;
	 QMap<QString,int> *mapPhaseLevel;
	 int mnuePhaseID;
	 int drawUS(CRelazioniUS*,int=1);
	 void connectUS(CRelazioniUS*);
	 void connectWBridges(CRelazioniUS*);

	protected:
	 void mousePressEvent(QMouseEvent*);

	protected slots:
	 void zoomIn();
	 void zoomOut();
	 void showPhases();

	public:
	 MatrixWidget(QWidget *parent=0, const char* name=0);
	 void drawHM(CRelazioniUS*);
	 void setPhaseMap(QMap<QString,int>* map);// { mapPhaseLevel=map; };
}


ctor()
{
...
canvas=new QCanvas(5000,5000); //FIXME - has to be dynamic

	mnuRClk = new QPopupMenu(this);
	mnuRClk->insertItem("Zoom in",this,SLOT(zoomIn()));
	mnuRClk->insertItem("Zoom out",this,SLOT(zoomOut()));
	mnuRClk->insertSeparator();
	mnuePhaseID=mnuRClk->insertItem("Show Phases",this,SLOT(showPhases()));
	mnuRClk->setCheckable(true);
...
}

setPhaseMap(...)
{
QMapIterator<QString,int> it;
 for( it=(*map).begin(); it!=(*map).end(); ++it )
  qDebug("key: %s - value: %d",it.key().ascii(),it.data());
//output is correct

 mapPhaseLevel=map;

 for( it=mapPhaseLevel->begin(); it!=mapPhaseLevel->end(); ++it )
	 qDebug("key: %s - value: %d",it.key().ascii(),it.data());
//output is correct
}

showPhases()
{
 QMapIterator<QString,int> it;

 mnuRClk->setItemChecked(id,!mnuRClk->isItemChecked(mnuePhaseID));

 qDebug("Show Phases method");
 qDebug("mapPhaseLevel: %p ",mapPhaseLevel);
 //pointer is still correct

//segfaults when accessing the map elements via ->begin() method
 for( it=mapPhaseLevel->begin(); it!=mapPhaseLevel->end(); ++it )
 {
  qDebug("Phase line at %d pixel height",(it.data()*100)+10);
  QCanvasLine *pl=new QCanvasLine(this->canvas);
  pl->setPen(Qt::DashLine);
  pl->setPoints(0,(it.data()*100)-50,this->canvas->width(),
(it.data()*100)-50);
  pl->show();
  QCanvasText *pt=new QCanvasText(this->canvas);
  pt->setText("Fase " + it.key());
  pt->move(0, (it.data()*100)-45);
  pt->show();
 }
}


- -----END code------

btw if i add a showPhases() call at the end of the drawHM(...) method in the
main object code, i get no segfaults and everything is fine...

> Make sure in the constructor, you're not doing this:
>
> class Object2
> {
> public:
>   QMap *myobject;
> }
>
> Object2::Object2(QMap *o) {
>    QMap *myobject = o;
> }
>
> As you have effectively created a local variable called myobject, and your
> class variable has been unitiailized;
>
i know :-)

i have a method like

Object2::setMap(QMap*o) {myobject=o;};

- --
Francesco Lamonica: f DOT lamonica AT tin DOT it

PGP Fingerprint: 5870 92BA 8DFF 1ACF DE2E  B94D 46EC 5505 7C64 4EF1
Favourite quote: There's no spoon

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFAqw8RRuxVBXxkTvERAu5tAKCnGBW7Kuqg8k5j5un4t11ih7dZIgCgrYhn
ivp8RBGkN6SV+nlFxhXLFRU=
=Tbf4
-----END PGP SIGNATURE-----