使用phtread_exit

时间:2019-11-23 20:22:20

标签: c++ pthreads

我想从一个线程返回一个std::pair<std::vector<int>, double>

设置如下:

void* thread_run(void *);
int main(int argc, char* argv[]) {

     std::pair<std::vector<int>, double> value;

     pthread_t t;
     pthread_create(&t, NULL, thread_run, NULL);

     // wait
     void* out;
     pthread_join(t, &out);

     value = *(std::pair<std::vector<int>, double> *)out;
     free(out);

     use(value);
}

void* thread_run(void* arg) {
    std::pair<std::vector<int>, double> * out = (std::pair<std::vector<int>, double>*)
        malloc(sizeof(std::pair<std::vector<int>, double>));

    out->first  = calc1();
    out->second = calc2();

    pthread_exit(out);
}

问题是我创建了内存泄漏。 Valgrind报告说:

  1. 有条件的跳转或移动取决于单位化的值,并指向分配out->first = calc1();

  2. 单位化值是由堆分配创建的,并且指向 malloc 行。

我正在使用gcc 5.4.0&C ++ 11和pthread库。我需要使用pthread。如何正确返回C ++ STL容器以避免内存泄漏。

3 个答案:

答案 0 :(得分:1)

您的程序具有未定义的行为,因为您为out分配了内存,但从未在该内存中构造对象。

然后用out->first = calc1();尝试访问不存在的对象的成员,这会导致未定义的行为。

如果您需要手动管理内存,则需要使用new

auto out = new std::pair<std::vector<int>, double>{};

,然后使用

将其删除
delete static_cast<std::pair<std::vector<int>, double>*>(out);

请注意,您需要删除与创建指针时使用的指针类型相同的指针。您可能要在返回时立即进行投射。

在C ++中,使用malloc几乎总是错误的,您应该使用std::thread,它带有适当的可移植C ++接口,而不是pthread提供的仅POSIX C接口。

答案 1 :(得分:1)

这如何:不要在堆上分配。

您已成功在value中创建了一个具有自动存储期限的名为main()的货币对。只需使用它即可。

#include <vector>
#include <iostream>

#include <pthread.h>

void* thread_run(void *);

int main(int argc, char* argv[]) {
     std::pair<std::vector<int>, double> value;

     pthread_t t;
     pthread_create(&t, NULL, thread_run, &value);

     // Wait.  Do not need to retrieve results, which are available in `value`.
     pthread_join(t, nullptr);

     std::cout << "Results: " << value.first.at(1) << "; " << value.second << '\n';
}

void* thread_run(void* arg) {
    std::pair<std::vector<int>, double>& out = *static_cast<std::pair<std::vector<int>, double>*>(arg);

    out.first  = std::vector<int>{{1, 2, 3}};
    out.second = 42.0;

    pthread_exit(arg);
}

Runnable example on Coliru

答案 2 :(得分:0)

您只需返回指向它的指针,就像其他任何东西一样。不要使用output.pdf,而要使用1.pdf。请记住使用正确的类型来呼叫malloc

new
  

如果要使用malloc路由,我是否必须放弃从线程返回std容器?

一点也不,但请记住正确调用对象的构造函数和析构函数。可能会有这样的事情:

delete