P线程从不同大小的整数转换为指针

时间:2022-06-11 15:13:02

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的指针并取消引用。