如何释放主线程函数分配的内存
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);
从您要发回的线程函数(使用 return
或 pthread_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 *
不兼容的类型,可能具有或不具有相同的表示形式甚至大小,尤其是不能互为别名。
我已经在线程函数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);
从您要发回的线程函数(使用 return
或 pthread_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 *
不兼容的类型,可能具有或不具有相同的表示形式甚至大小,尤其是不能互为别名。