我想了解此代码的行为。
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;
}
此代码导致120000字节的内存泄漏,因为变量a未被破坏,因此当我明确删除它时,泄漏消失,一切都应该没问题。
现在,如果我不是动态分配a,我使用静态分配,多次调用析构函数!!!
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;
}
和输出是 析构函数叫,一个是0 现在a是0 析构函数叫,一个是0 现在a是0 析构函数叫,一个是0 现在a是0 析构函数叫,一个是0 现在a是0 析构函数叫,一个是0 现在a是0 析构函数叫,一个是0 现在a是0 析构函数调用,一个是0x75e300 现在a是0 分段错误
析构函数被称为N次!!
现在我想知道如何使用boost :: thread安全地分配和释放类成员变量和对象,以及为什么线程析构函数不会显式处理类析构函数。
有人可以给我一个暗示吗? boost :: smart_ptr应该帮帮我吗?我必须用malloc分配内存(因为我需要使用一些旧的C API),我怎么能线程安全地做呢?
答案 0 :(得分:1)
它应该是&amp; a在第二种情况下吗?
boost::thread Foothread( &Foo::run, &a);
答案 1 :(得分:1)
两个版本在线程1中创建类Foo的对象,并从后台线程(线程2)调用其run
方法。当run
返回时,此后台线程终止。
run
实际上初始化了类Foo
的对象。您的代码中的一个问题是,您可能会执行一些非常长的计算,有时会在线程1 中完成a
的初始化之前在线程1 中访问“a” 。这会导致竞争状况。为避免这种情况,您应在访问Foothread.join()
中的Foo::a
之前致电a
。
其他一些观点:
NULL
不同a
new
创建的数组delete[] a;