3

In the Qt documentation, there is an example on the use of qobject_cast.

Following this example, I tried this:

#include <QApplication>
#include <QTimer>
#include <QDebug>

void test_cast(QObject *returnedObject)
{
    QTimer *timer = new QTimer;
    timer->setInterval(500);
    returnedObject = timer;
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);    

    QObject *obj;
    test_cast(obj);

    QTimer *timer = qobject_cast<QTimer *>(obj);

    if(timer)
        qDebug() << timer->interval(); //Should be 500

    return a.exec();
}

This code compiles but at runtime, the program crash at line:

QTimer *timer = qobject_cast<QTimer *>(obj);

The debugger says this is due to a segmentation fault in qobject_cast. I don't understand where is the problem. So I have a question, why there is a seg. fault ?

Tranqyll
  • 33
  • 6
  • Simply rewrite the code so that `test_cast` *returns* the new value: `QObject * obj = test_cast();`. That will fix it. There's no reason for `test_cast` to take any arguments, it only returns a value, after all. You might have minimized your code too much, so that the original requirement is not present :) – Kuba hasn't forgotten Monica Apr 25 '14 at 14:59

2 Answers2

5

The problem is in this function:

void test_cast(QObject *returnedObject)
{
    QTimer *timer = new QTimer;
    timer->setInterval(500);
    returnedObject = timer; //<-- changes the returnObject
}

You actually do not change the obj pointer passed to the test_cast function, but modify it's copy (returnedObject). As a result, the obj pointer in the main function remains uninitialized and your program crashes. To fix this, you need to modify your function in the following way:

void test_cast(QObject **returnedObject)
{
    QTimer *timer = new QTimer;
    timer->setInterval(500);
    *returnedObject = timer;
}

and call this function as:

QObject *obj;
test_cast(&obj);
vahancho
  • 20,808
  • 3
  • 47
  • 55
3

This is a comment to vahancho's answer.

You can also pass the pointer by reference:

void test_cast(QObject *&returnedObject);

However it may not be obvious that the pointer address can change if you are just looking at the function call, which will look like this:

QObject *obj;
test_cast(obj);
iiMaXii
  • 58
  • 4