So I am trying to figure out why I am getting this error in regards to p thread.
我想弄明白为什么我在p线程上得到这个错误。
I get the below error when I'm trying to run the code. I know it has to be something with p thread but not sure exactly what it is.
当我试图运行代码时,会得到下面的错误。我知道它一定是有p个线程的但不确定它到底是什么。
prime.c: In function ‘main’:
prime.c:33: warning: cast to pointer from integer of different size
prime.c: In function ‘isPrime’:
prime.c:50: warning: cast from pointer to integer of different size
any idea of what I'm doing wrong? I am including my code below. Thanks in advance for help.
知道我做错了什么吗?我把我的代码写在下面。谢谢你的帮助。
#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>
int *ptr;
int count;
int n;
void *isPrime(void *argp);
int main(int argc, char *argv[]) {
int i;
int num = 2;
int p;
pthread_t tid;
count = 0;
if (argc == 2 || argc == 3) {
printf("Argument : %s\n", argv[1]);
n = atoi(argv[1]);
if (argc == 3) {
p = atoi(argv[2]);
}
else {
p = 1;
}
ptr = (int *) malloc(n*sizeof(int));
while (count <= n) {
for (i = 1; i <= p; i++)
pthread_create(&tid, NULL, isPrime, (void *)num++);
}
for ( i = 0;i < n; i++) {
printf("%d ", *(ptr+i));
}
}
else {
printf("Invalid number of arguments\n");
}
}
void *isPrime(void *vargp) {
int i,flag = 0;
int num = (int)vargp;
for (i = 2; i <= num/2; i++) {
if (num % i == 0) {
flag = 1;
break;
}
}
if (!flag && count <= n) {
*(ptr + count) = num;
count++;
}
}
2 个解决方案
#1
1
Here's the obvious way to avoid the implementation-defined behavior inherent in casting between integers and pointers:
这里有一个明显的方法,可以避免在整数和指针之间的转换中固有的实现定义的行为:
while (count <= n) {
for (i = 1; i <= p; i++) {
int * iptr = malloc(sizeof *iptr);
if ( !iptr ) {
perror("Couldn't allocate memory."); /* Or other failure code */
exit(EXIT_FAILURE);
}
*iptr = num++;
pthread_create(&tid, NULL, isPrime, iptr);
}
}
and then in your thread function:
然后在线程函数中:
void *isPrime(void *vargp) {
int * iptr = vargp;
int num = *iptr;
free(iptr);
/* Rest of function */
return NULL;
}
As @WhozCraig points out, this is only one of the thread-related problems in your code.
正如@WhozCraig所指出的,这只是代码中与线程相关的问题之一。
#2
0
Edit
编辑
As WhozCraig and user3386109 point out, the changes I suggest below introduce a race condition. I haven't encountered this exact use case (passing different values to different threads through a single variable), so I can't offer any useful advice; simply take the explanation for why the warnings occur as what they are.
正如WhozCraig和user3386109所指出的,下面我建议的更改将引入一个race条件。我没有遇到过这个用例(通过一个变量将不同的值传递给不同的线程),因此我不能提供任何有用的建议;简单地解释一下为什么会出现这样的警告。
Original
原始
pthread_create(&tid, NULL, isPrime, (void *)num++);
pthread_create(&tid, NULL, isPrime, (void *)num+);
The expression (void *)num++
attempts to convert the type of the expression num++
to void *
; since integers and pointers may have different sizes and representations, this is potentially a bad idea.
表达式(void *)num+试图将表达式num+的类型转换为void *;因为整数和指针可能有不同的大小和表示,这可能是个坏主意。
Ideally, you should do something more like the following:
理想情况下,你应该做一些类似以下的事情:
{
pthread_create( &tid, NULL, isPrime, (void *) &num );
num++;
}
Unfortunately, (void *) &num++
won't work; the result of the ++
operator isn't an lvalue, so you can't apply the &
operator to it.
不幸的是,(void *)和num++无法工作;+运算符的结果不是lvalue,所以不能对它应用&运算符。
(void *) &num
is converting from one pointer type to void *
, which is safer than converting from an integer type to a pointer type.
&num从一个指针类型转换为void *,这比从整数类型转换为指针类型更安全。
Then, in the isprime
function, you would need to make the corresponding change:
然后,在isprime函数中,需要做相应的更改:
int num = *((int *)vargp);
That is, convert
vargp
back to a pointer to
int
and dereference it.
也就是说,将vargp转换为指向int的指针并取消引用。
#1
1
Here's the obvious way to avoid the implementation-defined behavior inherent in casting between integers and pointers:
这里有一个明显的方法,可以避免在整数和指针之间的转换中固有的实现定义的行为:
while (count <= n) {
for (i = 1; i <= p; i++) {
int * iptr = malloc(sizeof *iptr);
if ( !iptr ) {
perror("Couldn't allocate memory."); /* Or other failure code */
exit(EXIT_FAILURE);
}
*iptr = num++;
pthread_create(&tid, NULL, isPrime, iptr);
}
}
and then in your thread function:
然后在线程函数中:
void *isPrime(void *vargp) {
int * iptr = vargp;
int num = *iptr;
free(iptr);
/* Rest of function */
return NULL;
}
As @WhozCraig points out, this is only one of the thread-related problems in your code.
正如@WhozCraig所指出的,这只是代码中与线程相关的问题之一。
#2
0
Edit
编辑
As WhozCraig and user3386109 point out, the changes I suggest below introduce a race condition. I haven't encountered this exact use case (passing different values to different threads through a single variable), so I can't offer any useful advice; simply take the explanation for why the warnings occur as what they are.
正如WhozCraig和user3386109所指出的,下面我建议的更改将引入一个race条件。我没有遇到过这个用例(通过一个变量将不同的值传递给不同的线程),因此我不能提供任何有用的建议;简单地解释一下为什么会出现这样的警告。
Original
原始
pthread_create(&tid, NULL, isPrime, (void *)num++);
pthread_create(&tid, NULL, isPrime, (void *)num+);
The expression (void *)num++
attempts to convert the type of the expression num++
to void *
; since integers and pointers may have different sizes and representations, this is potentially a bad idea.
表达式(void *)num+试图将表达式num+的类型转换为void *;因为整数和指针可能有不同的大小和表示,这可能是个坏主意。
Ideally, you should do something more like the following:
理想情况下,你应该做一些类似以下的事情:
{
pthread_create( &tid, NULL, isPrime, (void *) &num );
num++;
}
Unfortunately, (void *) &num++
won't work; the result of the ++
operator isn't an lvalue, so you can't apply the &
operator to it.
不幸的是,(void *)和num++无法工作;+运算符的结果不是lvalue,所以不能对它应用&运算符。
(void *) &num
is converting from one pointer type to void *
, which is safer than converting from an integer type to a pointer type.
&num从一个指针类型转换为void *,这比从整数类型转换为指针类型更安全。
Then, in the isprime
function, you would need to make the corresponding change:
然后,在isprime函数中,需要做相应的更改:
int num = *((int *)vargp);
That is, convert
vargp
back to a pointer to
int
and dereference it.
也就是说,将vargp转换为指向int的指针并取消引用。