-1

I want to use QtConcurrent::run() for a member function, but it seems that it doesn't use the pointer to the instance. Instead, it looks like the default constructor is called

#include <QObject>
#include <QDebug>
#include <QtConcurrent>

class Foo : public QObject
{
    Q_OBJECT
public:
    Foo(int n = 0):n(n){}
    Foo(const Foo & f):Foo(f.n){}

    void foo(){qDebug() << "Foo " << n;}
    void bar(){QtConcurrent::run(this, &Foo::foo);}

private:
    int n;
};

void test(){
  Foo foo = Foo(2);
  foo.foo();
  foo.bar();
  QtConcurrent::run(&foo, &Foo::foo);
  QtConcurrent::run(&foo, &Foo::bar);
}

And the results of running test() are :

Foo  2
Foo  0 // Should be a 2
Foo  0 // Should be a 2
Foo  0 // Should be a 2

Edit : My instance indeed went out of scope. This code works fine

void test(){
    Foo * foo = new Foo(2);
    foo->foo();
    foo->bar();
    QtConcurrent::run(foo, &Foo::foo);
    QtConcurrent::run(foo, &Foo::bar);
}
B. Decoster
  • 7,723
  • 1
  • 32
  • 52

1 Answers1

3

Making a call to an object which has been destructed is undefined behavior. What is happening is that when QtConcurrent::run effectively execute Foo::bar, the parameter foo has been destructed.

If I try to replicate your code I have:

Foo  2 
Foo  1730312062 
Foo  1730312062 

Issue come from the fact that the object foo is on the stack and will be invalid as soon as test return. Provide a greater lifetime to your object.

UmNyobe
  • 22,539
  • 9
  • 61
  • 90