如何释放主线程函数分配的内存

How to free memory allocated by thread-function in the main

我已经在线程函数f1中分配了heap内存,这个内存是用来计算堆区的值的,以便main函数可以看到。

线程函数定义如下:

void *f1(void *input){


        int sum = (int*)malloc(sizeof(int));
        /* Do calculation */   
        pthread_exit((void*)&sum);
}

在上面的代码中,sum是堆分配的存储,其地址作为return值传递给main()中的sum1

join main() 中的线程是这样的:

void *sum1;
pthread_join(tid1,(void**)&sum1);

检索到该值后,我想 free 分配的内存。 当我主要使用 free 时,它会抱怨 munmap_chunk(): invalid pointer

我怎样才能明确和安全地free这个内存?

你应该发回指针,而不是它的地址

pthread_exit(sum);
...
pthread_join(tid1, &sum1);

从您要发回的线程函数(使用 returnpthread_exit())一个指针。
pthread_join()你想获得这个指针但是pthread_join()的结果是一个整数来报告success/failure.
然后我们必须声明一个指针变量(sum1这里)来存储预期的结果,并提供pthread_join()这个变量的地址,以便它可以被更新(同样的方式我们提供地址给scanf() 以便更新提取的变量)。

您的代码中的问题是使用 casts。在 C 语言中,大多数时候指针转换表示 错误的构造 。值得注意的是,在此示例中,如果正确使用构造,则不需要强制转换:

// no cast required because malloc returns void * and void * can be converted
// to a pointer to int without a cast
int *sum = malloc(sizeof (int));

// no cast required because int * can be converted to a void * without a cast
pthread_exit(sum);

void *sum1;

// no cast required because the address of void * is a void **!
pthread_join(tid1, &sum1);

唯一需要强制转换的地方是如果您现在将此 void * value 转换为 int * inline:

int value = *(int *)sum1;

但是你也可以通过赋值来转换它,然后再说一遍,不需要转换:

int *value_ptr = sum1;
printf("The value was %d\n", *value_ptr);
free(value_ptr);

经验法则是,如果您比编译器更了解一些东西,那么强制转换是可以的 - 例如 "truncate this value to uint8_t" 或 "this void pointer actually points to an int, but I am not assigning it to one to save keystrokes" - 但仅仅让警告静音通常是不行的。


有些程序员是这样写代码的:

int *ptr;
pthread_join(tid1, (void **)&ptr);

这样的代码并不严格符合 int *void * 不兼容的类型,可能具有或不具有相同的表示形式甚至大小,尤其是不能互为别名。