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 withnew
must be deleted withdelete[] a;
Should it be &a in the second case?
boost::thread Foothread( &Foo::run, &a);
精彩评论