*** glibc检测到*** free():指针无效

时间:2013-07-31 19:59:38

标签: c++ pointers pthreads free glibc

我有以下代码,每当我运行代码时都会产生*** glibc detected *** free(): invalid pointer错误。

main.h

#ifndef PTHREAD_CALC_H_
#define PTHREAD_CALC_H_

void* task(void*);

#endif

main.cxx

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>
#include "main.h"

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

    pthread_t *threads = (pthread_t*)malloc(sizeof(pthread_t)*2);
    double  *temp;

    double sum = 0.0;
    for (int j = 0; j < 2; j++) {
        pthread_create(&(threads[j]), NULL, task, NULL);
    }

    for (int j = 0; j < 2; j++) {
        pthread_join(threads[j], (void**)(&temp));
        sum += *temp;
    }

    free(threads);
    free(temp);

    return 0;
}

void* task(void *data) {
    double sum = 5;
    pthread_exit((void*)&sum);
    return NULL;
}

我很难确定导致错误的原因。非常感谢任何帮助。如果我能提供其他任何帮助查明问题,请告诉我。

谢谢

修改

为了完成,以下是按预期执行的结果代码:

main.cxx

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>
#include "main.h"

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

    pthread_t *threads = (pthread_t*)malloc(sizeof(pthread_t)*2);
    double  *temp;

    double sum = 0.0;
    for (int j = 0; j < 2; j++) {
        pthread_create(&(threads[j]), NULL, task, NULL);
    }

    for (int j = 0; j < 2; j++) {
        pthread_join(threads[j], (void**)&temp);
        sum += temp;
        delete temp;
    }

    free(threads);
    return 0;
}

void* task(void *data) {
    double* sum = new double;
    *sum = 5.0;
    pthread_exit(static_cast<void*>(sum));
}

2 个答案:

答案 0 :(得分:1)

目前,您的线程任务在线程堆栈上返回一些值。当线程完成时,不能保证* temp将指向有效的东西。

这次通话后

pthread_join(threads[j], (void**)(&temp));

temp指向线程中sum的旧位置,但如果线程完成则不再存在。使用它会导致未定义的行为。

稍后你释放临时指向另一个堆栈上的double的temp,但是由于堆栈分配超出范围时会自动释放,因此无需释放。

free(temp);

希望你可能想做的是:

void* task(void *data) {
    double* sum = new double;
    *sum = 5;
    pthread_exit(static_cast<void*>(sum) );
}

然后在加入线程后的main中

delete temp;

答案 1 :(得分:0)

在您的代码中,您声明:

double  *temp;

你从来没有对地址进行过malloc,但是后来你释放了它。这将产生错误。删除免费(临时),它应该工作。实际上,虽然您通过解除引用* temp而没有存储来引入新错误。