简体   繁体   English

如何将整数转换为void指针?

[英]How to cast an integer to void pointer?

While working with Threads in C, I'm facing the warning 在C中使用Threads时,我面临警告

"warning: cast to pointer from integer of different size" “警告:从不同大小的整数强制转换为指针”

The code is as follows 代码如下

#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
#include<pthread.h>
void *print(void *id)
{
 int a=10;
 printf("My thread id is %ld\n",pthread_self());
 printf("Thread %d is executing\n",id);
 return (void *) 42;
}

int main()
{
 pthread_t th[5];
 int t;
 int i;
 int status;
 void *ret;
 for(i=0;i<5;i++)
 {
   status=pthread_create(&th[i],NULL,print,(void *)i); //Getting warning at this line
   if(status)
   {
    printf("Error creating threads\n");
    exit(0);
   }
   pthread_join(th[i],&ret);
   printf("--->%d\n",(int *)ret);
 }
 pthread_exit(NULL);
}

Can anybody explain how to pass an integer to a function which receives (void * ) as a parameter? 谁能解释如何将整数传递给接收(void *)作为参数的函数?

This is a fine way to pass integers to new pthreads, if that is what you need. 如果您需要的话,这是将整数传递给新pthread的一种好方法。 You just need to suppress the warning, and this will do it: 您只需要禁止显示警告,就可以做到这一点:

#include <stdint.h>

void *threadfunc(void *param)
{
    int id = (intptr_t) param;
    ...
}

int i, r;
r = pthread_create(&thread, NULL, threadfunc, (void *) (intptr_t) i);

Discussion 讨论区

This may offend your sensibilities, but it's very short and has no race conditions (as you'd have if you used &i ). 这可能会冒犯您的敏感性,但是它很短并且没有竞争条件(如果使用&i ,您会遇到这种情况)。 No sense in writing a few dozen lines of extra code just to get a bunch of numbered threads. 仅仅为了获得一堆编号的线程而编写几十行额外的代码是没有意义的。

Data races 数据竞赛

Here is a bad version with a data race: 这是带有数据争用的错误版本:

#include <pthread.h>
#include <stdio.h>

#define N 10

void *thread_func(void *arg)
{
    int *ptr = arg;
    // Has *ptr changed by the time we get here?  Maybe!
    printf("Arg = %d\n", *ptr);
    return NULL;
}

int main()
{
    int i;
    pthread_t threads[N];
    for (i = 0; i < N; i++) {
        // NO NO NO NO this is bad!
        pthread_create(&threads[i], NULL, thread_func, &i);
    }
    for (i = 0; i < N; i++) {
        pthread_join(threads[i], NULL);
    }
    return 0;
}

Now, what happens when I run it with the thread sanitizer? 现在,当我使用线程清理程序运行它时会发生什么?

(Also, check out how it prints "5" twice...) (另外,检查两次如何打印“ 5” ...)

==================
WARNING: ThreadSanitizer: data race (pid=20494)
  Read of size 4 at 0x7ffc95a834ec by thread T1:
    #0 thread_func /home/depp/test.c:9 (a.out+0x000000000a8c)
    #1 <null> <null> (libtsan.so.0+0x000000023519)

  Previous write of size 4 at 0x7ffc95a834ec by main thread:
    #0 main /home/depp/test.c:17 (a.out+0x000000000b3a)

  Location is stack of main thread.

  Thread T1 (tid=20496, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x0000000273d4)
    #1 main /home/depp/test.c:18 (a.out+0x000000000b1c)

SUMMARY: ThreadSanitizer: data race /home/depp/test.c:9 thread_func
==================
Arg = 1
Arg = 2
Arg = 3
Arg = 4
Arg = 5
Arg = 6
Arg = 7
Arg = 8
Arg = 9
Arg = 5
ThreadSanitizer: reported 1 warnings

you can pass the int value as void pointer like (void *)&n where n is integer, and in the function accept void pointer as parameter like void foo(void *n); 您可以将int值作为void指针传递,例如(void *)&n ,其中n是整数,并且在函数中将void指针作为参数传递给参数,例如void foo(void *n); and finally inside the function convert void pointer to int like, int num = *(int *)n; 最后在函数内部将void指针转换为int,例如int num = *(int *)n; . this way you won't get any warning. 这样您就不会收到任何警告。

you can do something like this: 您可以执行以下操作:

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <pthread.h>
struct th {
    pthread_t thread;
    int id;
    int ret;
};

void *print(void *id) {
    int a=10;
    struct th *self = (struct th *) id;
    printf("My thread id is %ld\n",pthread_self());
    printf("Thread %d is executing\n",self->id);
    self->ret = random();
    return;
}

int main(void) {
    struct th th[5];
    int t;
    int i;
    int status;
    void *ret;
    for(i=0;i<5;i++) {
        th[i].id = i;
        status=pthread_create(&th[i].thread,NULL,print,&th[i]); //Getting warning at this line
        if(status) {
            printf("Error creating threads\n");
            exit(0);
        }
    }
    for (i=0;i<5;i++) {
        pthread_join(th[i].thread,&ret);
        printf("%d--->%d\n",th[i].id,th[i].ret);

    }
    pthread_exit(NULL);
}

will output: 将输出:

My thread id is 4496162816
My thread id is 4497870848
My thread id is 4498944000
My thread id is 4498407424
Thread 0 is executing
Thread 1 is executing
My thread id is 4499480576
Thread 3 is executing
Thread 2 is executing
0--->1804289383
Thread 4 is executing
1--->846930886
2--->1714636915
3--->1681692777
4--->1957747793

passing a unique pointer to each thread wont race, and you can get/save any kind of information in the th struct 向每个线程传递唯一的指针将不会引起竞争,您可以在结构中获取/保存任何类型的信息

change: 更改:

status=pthread_create(&th[i],NULL,print,(void *)i);

to: 至:

status=pthread_create(&th[i],NULL,print,(reinterpret_cast<void*>(i));

The reinterpret_cast makes the int the size of a pointer and the warning will stop. reinterpret_cast使int成为指针的大小,并且警告将停止。 Basically its a better version of (void *)i. 基本上,它是(void *)i的更好版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM