QSignalMapper gives me a Segmentation fault

181 views Asked by At

I want to write a method that creates a button and connects it to a slot that takes a string:

void Widget::createButton(const char *member)
{
    QPushButton *button = new QPushButton(this);
    QSignalMapper *signalMapper = new QSignalMapper(this);
    signalMapper->setMapping(button, "Test");

    connect(signalMapper, SIGNAL(mapped(QString)), this, member);
    connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
}

void Widget::sendCom(QString data)
{
    std::cout << data << std::endl;
}

on an instance of Widget (just a subclass of QWidget) i do:

widget->createButton(SLOT(sendCom(QString))

without the mapping it worked fine and i copied the mapping syntax from a similar piece of code that also works fine. Compiles with no Errors but when i press a button i end up with a segmentation fault. Any ideas?

Edit: like peppe suggested i ran valgrind and here is the output

==31303== Invalid read of size 8
==31303==    at 0x3E1632DBF0: QAbstractButton::text() const (in /usr/lib64/libQtGui.so.4.6.2)
==31303==    by 0x407A66: Widget::sendCom(QString) (widget.cpp:36)
==31303==    by 0x40804E: Widget::qt_metacall(QMetaObject::Call, int, void**) (moc_widget.cpp:72)
==31303==    by 0x3E0FB6A7DE: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E0FB6DEE4: QSignalMapper::mapped(QString const&) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E0FB6E009: QSignalMapper::map(QObject*) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E0FB6F23F: QSignalMapper::qt_metacall(QMetaObject::Call, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E0FB6A7DE: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E165DCE51: QAbstractButton::clicked(bool) (in /usr/lib64/libQtGui.so.4.6.2)
==31303==    by 0x3E1632E75A: ??? (in /usr/lib64/libQtGui.so.4.6.2)
==31303==    by 0x3E1632FADA: ??? (in /usr/lib64/libQtGui.so.4.6.2)
==31303==    by 0x3E1632FD4B: QAbstractButton::mouseReleaseEvent(QMouseEvent*) (in /usr/lib64/libQtGui.so.4.6.2)
==31303==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
==31303== 
==31303== 
==31303== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==31303==  Access not within mapped region at address 0x8
==31303==    at 0x3E1632DBF0: QAbstractButton::text() const (in /usr/lib64/libQtGui.so.4.6.2)
==31303==    by 0x407A66: Widget::sendCom(QString) (widget.cpp:36)
==31303==    by 0x40804E: Widget::qt_metacall(QMetaObject::Call, int, void**) (moc_widget.cpp:72)
==31303==    by 0x3E0FB6A7DE: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E0FB6DEE4: QSignalMapper::mapped(QString const&) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E0FB6E009: QSignalMapper::map(QObject*) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E0FB6F23F: QSignalMapper::qt_metacall(QMetaObject::Call, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E0FB6A7DE: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303==    by 0x3E165DCE51: QAbstractButton::clicked(bool) (in /usr/lib64/libQtGui.so.4.6.2)
==31303==    by 0x3E1632E75A: ??? (in /usr/lib64/libQtGui.so.4.6.2)
==31303==    by 0x3E1632FADA: ??? (in /usr/lib64/libQtGui.so.4.6.2)
==31303==    by 0x3E1632FD4B: QAbstractButton::mouseReleaseEvent(QMouseEvent*) (in /usr/lib64/libQtGui.so.4.6.2)

This helps locating address, but still i do not know how to debug.

EDIT: The Problem is solved. I shortened the code to be more precise but this has hidden the actual cause

Create Button actually looked like this:

void Widget::createButton(const QString &text, int x, int y, const char *member, QString &data)
{
    QPushButton *button = new QPushButton(this);
    signalMapper = new QSignalMapper(this);
    signalMapper->setMapping(button, data);
    connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(sendCom(QString)));
    connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
    button->setText(text);
    button->move(x, y);
    button->show();
}


void Widget::sendCom(QString data)
{
    QPushButton *clickedButton = qobject_cast<QPushButton *>(sender());
    std::cout << qPrintable(data) << std::endl;
    std::cout << qPrintable(clickedButton->text()) << std::endl;
}

The qobject_cast caused the SIGSEGV. It still is to clarify why it does so.

0

There are 0 answers