请考虑以下代码:
void* run(void* arg) {
int* array=(int*)arg;
printf("In run!\n");
int i;
for (i=0; i<10; i++) {
printf("%d ",array[i]);
}
printf("\n");
return (void*)15;
}
int main() {
pthread_t my_thread;
int array[10]={0};
void* ret;
int i;
for (i=0; i<10; i++) {
array[i]=i+1;
}
if (pthread_create(&my_thread, NULL, run, (void*)array)!=0) {
perror("thread creation failed");
return 1;
}
pthread_join(my_thread, &ret);
printf("thread finished and returned %d\n", *(int*)ret); // segfault. why??
return 0;
}
我正在尝试获取由创建的线程返回的值15,但由于某种原因,最后一个printf会引发分段错误 .
分段错误的原因是什么,获取返回值15的正确方法是什么?
我也试过这个:printf("thread finished and returned %d\n", *(*(int*)ret));
这导致了一个错误:
error: invalid type argument of unary ‘*’ (have ‘int’)
还有这个:printf("thread finished and returned %d\n", *(int*)(*ret));
这也导致了错误(和警告):
*warning: dereferencing ‘void ’ pointer [enabled by default] error: invalid use of void expression
什么是正确的方法,最重要的是,这个段错误的原因是什么?
1 回答
失败的原因是你的线程返回一个整数代替
void*
,而main
中的代码试图取消引用它 .同时做这两件事是违法的,但你可以分别做到这两件事:
如果在指针中返回
int
,可以在转换为void*
之前将其强制转换为uintptr_t,然后反向执行序列以返回int
,或者如果你想在
main
中取消引用,你需要将int
放在内存中,然后传回指向该内存的指针,以便在main
中取消引用它 .我会使用第一种方法,如下所示:
请记住包含
<stdint.h>
以使用uintptr_t
类型 .使用第二种方法有点棘手:
您可以通过在调用者中为结果分配缓冲区来简化它,但这种方式比使用
uintptr_t
方法更难 .