i have a segment fault when it calls the function unit_thread_data,Actually it is caused by ~Data(). thread1 is all right, but thread2 cause the segment fault, the whole code is as fallows:(forgive the poor code style), error info is double free or corruption. Other info: gcc5.4.0, centos7. any help? thank you very much!
#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;
}
CodePudding user response:
delete[] pthread_data[i].d->A_;
This deletes the A_
member of your Data
class, an int *
.
Immediately afterwards, this happens:
delete pthread_data[i].d;
And this deletes the Data
itself. Data
's destructor then does the following:
if(A_) {
delete A_;
}
This then proceeds to attempt delete
the same pointer. This should be delete[]
d instead of delete
d in the first place, but this is moot because this pointer is already delete
d, and this tries to delete
it a 2nd time.
This results in undefined behavior.
CodePudding user response:
It is because you first delete member A_
here:
delete[] pthread_data[i].d->A_;
without assigning nullptr
to A_
afterwards, and then you call delete A_;
in the destructor.
Apart from that, in your code it is not clear who should be the owner of the memory allocated under A_
(functions _add
and unit_thread_data
, or a class itself), hence it is easy to do this kind of mistakes.
Quick fix (not recommended): just remove your destructor's body, and let your external functions _add
and unit_thread_data
manage the memory.
Better fix (recommended): think about who should be the owner of the allocated data (I would say class Data
) and use std::unique_ptr
if you can.
CodePudding user response:
You need to assign NULL after deleting A_.