Home > front end >  multithread segment fault destructors
multithread segment fault destructors

Time:11-26

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 deleted in the first place, but this is moot because this pointer is already deleted, 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_.

  • Related