开发者

boost::thread and destructor of contained classes

开发者 https://www.devze.com 2023-03-31 23:53 出处:网络
I would like to understand the behaviour of this code. class Foo { public: Foo(); ~Foo(); void run(); int* get();

I would like to understand the behaviour of this code.

class Foo
{
      public:
            Foo();
            ~Foo();
            void run();
            int* get();
    private:
            int *a;
};

Foo::Foo()
{
     a=NULL;       
}
void Foo::run()
{
       if ( a==NULL)
            a = new int[30000];
}

int* Foo::get()
{
    return a;
}

Foo::~Foo()
{
    cout << "destructor called" << endl;
    if ( a!=NULL)
            delete a;
}

int main()
{
        Foo *a = new Foo();

        boost::thread Foothread( &Foo::run, a);
        // Some very long computation that sometimes access 

        int *b  = a->get();
        cout << *b << endl; 
        //Foothread.join();
        //delete a;
        //Foothread.join();

        return 0;
}

This code causes a memory leak of 120000 bytes because variable a is not destructed, so when I explicitly delete it the leak disappers and everything should be ok.

Now if I instead of dynamically allocate a, I use static allocation the destructor is called many times!!!

int main()
{
        Foo a;

        boost::thread Foothread( &Foo::run, a);
        // Some very long computation that sometimes access "a"
        Foothread.join();
        int *b  = a.get();
        cout << *b << endl; 

        return 0;
}

and the ouput is destructor called, a was 0 Now a is 0 destructor called, a was 0 Now a is 0 destructor called, a was 0 Now a is 0 destructor called, a was 0 Now a is 0 destructor called, a was 0 Now a is 0 destructor called, a was 0 Now a is 0 destructor called, a was 0x75e300 Now a is 0 Segmentation fault

The destructor is called N times!!

Now I would like to know how to safe allocate and deallocate 开发者_JS百科both class member variable and objects using boost::thread and why the thread destructor doesn't handle the class destructor explicitly.

Could someone give me an hint? Should boost::smart_ptr help me? I have to allocate memory with malloc (because I need to use some old C API), how can I do it thread-safely?


Both versions create an object of class Foo in Thread 1 and call its run method from a background thread (Thread 2). This background thread terminates, when run returns.

run actually initializes the object of class Foo. One problem in your code is, that you may do some very long computation that sometimes access "a" in Thread 1 before Thread 2 finished the intialization of a. This causes a race condition. To avoid it, you should call Foothread.join() before you access the Foo::a in a.

Some other points:

  • in Foo::~Foo() you do not need to check if the pointer about to delete differs from NULL
  • an array a created with new must be deleted with delete[] a;


Should it be &a in the second case?

boost::thread Foothread( &Foo::run, &a);
0

精彩评论

暂无评论...
验证码 换一张
取 消