多线程段故障析构函数
multithread segment fault destructors
我调用函数unit_thread_data时出现段错误,其实是~Data()引起的。 thread1 没问题,但是thread2 导致segment fault,整个代码如下:(原谅糟糕的代码风格),错误信息是double free or corruption。其他信息:gcc5.4.0,centos7。有帮助吗?非常感谢!
#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
class Data
{
public:
int* A_;
Data()
{
cout<<"111\n";
A_=NULL;
}
~Data()
{
cout<<"222\n";
if(A_) {
delete A_;
}
}
};
struct thread_data_t
{
Data* d;
};
void* _add(void* _pthread_data)
{
thread_data_t* pthread_data = (thread_data_t*) _pthread_data;
pthread_data->d->A_ = new int[2];
pthread_data->d->A_[0] = 1;
pthread_data->d->A_[1] = 2;
std::cout<<pthread_data->d->A_[0]+pthread_data->d->A_[1]<<endl;
return (void*)0;
}
void unit_thread_data(thread_data_t* pthread_data)
{
for(int i=0;i<2;i++)
{
delete[] pthread_data[i].d->A_;
delete pthread_data[i].d;
}
delete[] pthread_data;
}
int main()
{
int num_threads = 2;
pthread_t threads[num_threads];
thread_data_t* pthread_data = new thread_data_t[num_threads];
for(int i=0;i<num_threads; i++)
{
pthread_data[i].d = new Data();
}
for (int i=0; i<num_threads; i++) {
pthread_create(&threads[i], NULL, _add, (void*)(pthread_data+i));
}
for (int i=0; i<num_threads; i++) {
pthread_join(threads[i], NULL);
}
sleep(1);
unit_thread_data(pthread_data);
return 0;
}
delete[] pthread_data[i].d->A_;
这将删除 Data
class 的 A_
成员,int *
。
紧接着,这发生了:
delete pthread_data[i].d;
这会删除 Data
本身。 Data
的析构函数然后执行以下操作:
if(A_) {
delete A_;
}
然后继续尝试 delete
相同的指针。首先应该是 delete[]
d 而不是 delete
d,但这没有实际意义,因为这个指针已经是 delete
d,并且它试图 delete
它是第二个时间。
这会导致未定义的行为。
因为你先删除了这里的成员A_
:
delete[] pthread_data[i].d->A_;
之后没有将 nullptr
分配给 A_
,然后在析构函数中调用 delete A_;
。
除此之外,在您的代码中不清楚谁应该是 A_
下分配的内存的所有者(函数 _add
和 unit_thread_data
,或者 class本身),所以很容易犯这种错误。
快速修复(不推荐):只需删除析构函数的主体,让外部函数 _add
和 unit_thread_data
管理内存。
更好的修复(推荐):考虑谁应该是分配数据的所有者(我会说class Data
),如果可以的话使用std::unique_ptr
。
删除A_后需要赋值NULL。
我调用函数unit_thread_data时出现段错误,其实是~Data()引起的。 thread1 没问题,但是thread2 导致segment fault,整个代码如下:(原谅糟糕的代码风格),错误信息是double free or corruption。其他信息:gcc5.4.0,centos7。有帮助吗?非常感谢!
#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
class Data
{
public:
int* A_;
Data()
{
cout<<"111\n";
A_=NULL;
}
~Data()
{
cout<<"222\n";
if(A_) {
delete A_;
}
}
};
struct thread_data_t
{
Data* d;
};
void* _add(void* _pthread_data)
{
thread_data_t* pthread_data = (thread_data_t*) _pthread_data;
pthread_data->d->A_ = new int[2];
pthread_data->d->A_[0] = 1;
pthread_data->d->A_[1] = 2;
std::cout<<pthread_data->d->A_[0]+pthread_data->d->A_[1]<<endl;
return (void*)0;
}
void unit_thread_data(thread_data_t* pthread_data)
{
for(int i=0;i<2;i++)
{
delete[] pthread_data[i].d->A_;
delete pthread_data[i].d;
}
delete[] pthread_data;
}
int main()
{
int num_threads = 2;
pthread_t threads[num_threads];
thread_data_t* pthread_data = new thread_data_t[num_threads];
for(int i=0;i<num_threads; i++)
{
pthread_data[i].d = new Data();
}
for (int i=0; i<num_threads; i++) {
pthread_create(&threads[i], NULL, _add, (void*)(pthread_data+i));
}
for (int i=0; i<num_threads; i++) {
pthread_join(threads[i], NULL);
}
sleep(1);
unit_thread_data(pthread_data);
return 0;
}
delete[] pthread_data[i].d->A_;
这将删除 Data
class 的 A_
成员,int *
。
紧接着,这发生了:
delete pthread_data[i].d;
这会删除 Data
本身。 Data
的析构函数然后执行以下操作:
if(A_) {
delete A_;
}
然后继续尝试 delete
相同的指针。首先应该是 delete[]
d 而不是 delete
d,但这没有实际意义,因为这个指针已经是 delete
d,并且它试图 delete
它是第二个时间。
这会导致未定义的行为。
因为你先删除了这里的成员A_
:
delete[] pthread_data[i].d->A_;
之后没有将 nullptr
分配给 A_
,然后在析构函数中调用 delete A_;
。
除此之外,在您的代码中不清楚谁应该是 A_
下分配的内存的所有者(函数 _add
和 unit_thread_data
,或者 class本身),所以很容易犯这种错误。
快速修复(不推荐):只需删除析构函数的主体,让外部函数 _add
和 unit_thread_data
管理内存。
更好的修复(推荐):考虑谁应该是分配数据的所有者(我会说class Data
),如果可以的话使用std::unique_ptr
。
删除A_后需要赋值NULL。