C++ 如何通过函数的void指针参数传递int值并将其转换回int值?

C++ 如何通过函数的void指针参数传递int值并将其转换回int值?,c++,multithreading,void-pointers,C++,Multithreading,Void Pointers,我正在尝试创建一个多线程程序,该程序为获取它的每个文件(file1.txt到file20.txt)创建一个线程,我需要使用pthread\u create将一个变量传递到函数中。我很难将int值传递到函数中,因为pthread\u create只接受void*,所以我的函数必须接受void* 我有一些指针方面的经验,但我不太理解空指针的概念。据我所知,我的pthread\u create应该看起来与这个pthread\u create类似(&tids[I],NULL,getSales,(void

我正在尝试创建一个多线程程序,该程序为获取它的每个文件(file1.txt到file20.txt)创建一个线程,我需要使用
pthread\u create
将一个变量传递到函数中。我很难将int值传递到函数中,因为
pthread\u create
只接受
void*
,所以我的函数必须接受
void*

我有一些指针方面的经验,但我不太理解空指针的概念。据我所知,我的
pthread\u create
应该看起来与这个
pthread\u create类似(&tids[I],NULL,getSales,(void*)I)

在main()中:

使用名称空间std;
int main(int argc,字符**argv){
int numfiles=20;
//线程ID
pthread_t tids[numfiles];
//创建线程

对于(int i=1;i您将
int
强制转换为
void*
。要撤消它,请将
void*
强制转换回
int
。因此:

int* num = (int*)fileNum;
应该是:

int num = (int)fileNum;

经典的解决方案是使用一个对象数组来表示每个pthread的参数。也就是说,每个线程都有一个关联的唯一位置来保存其参数。您只需要传递一个指向该唯一位置的指针

下面是一个例子:

void *pthread_func(void *_arg) {
    int arg = *(int*)_arg; // we're receiving an int
    // ...
}

int main() {
    pthread_t threads[20];
    int       args[20]; // unique arg location for each thread

    for (int i = 0; i < 20; ++i) {
        args[i] = (whatever you want to pass)

        // create the thread, give it its unique arg location
        pthread_create(&threads[i], NULL, pthread_func, &args[i]);
    }

    // ... join the threads, etc. ...
}

转换为
int
(不是
int*
)如果你不熟悉多线程的马尾辫指针,除非你在其他语言中使用过它,否则听起来有点过早。它只会让你对Nico所说的话产生混淆,另外你可能想查看
GPOINTER\u to\u INT
/
GINT\u to\u指针
宏以避免编译器警告。使用std::thread并避免BRW AltoCuel.BTW不编译C++与<代码> GCC < /代码>。它是“代码> G++<代码> >如果我仍然得到,并且错误<代码>从“空虚*”到“int”,则在该行上丢失精度,并从“不同代码的大小”<代码> >“代码> > pthRead创建< /代码>调用警告。nge
pthread_create(&tids[i],NULL,getSales,(void*)i);
to
pthread_create(&tids[i],NULL,getSales,(void*)&i);
它删除了警告,但我仍然在使用
int num=(int)fileNum;
@CSstudent现在您正在创建一个悬空指针;您不能通过猜测编程;)实际上,您应该动态地分配一些包含所需数据的结构。编译器在这两种情况下都是正确的;即使这样,这也不是使用指针的好方法。(通过
intptr\t
的往返可能会解决您在这种情况下的问题)@LightnessRacesinOrbit:你的评论指的是
intptr\u t
,但我认为
intptr\u t
不一定适用于此处要求的往返行程。我对另一个答案的评论包含一个解释。我可以想象,你知道所有微妙的细节,并将其隐藏在“可能”一词后面.然而,在当前的形式中,你对
intptr\t
的引用可能会激励人们基于此构建他们的黑客解决方案。你愿意启发我们吗?@Julius你绝对可以接受
intptr\t
。当然,在算法的早期阶段,你扔给它的
int
不会被保留,但是t我假设这已经在前面考虑过了;)这是传递大于
void*
的参数所需要的,但是由于原始参数合适,所以没有必要(注意原始代码传递
(void*)I
而不是
&I
)迂腐的注释:
intptr\u t
能够容纳任何指针。因此,往返
void*
std::intptr\u t
void*
保证返回原始指针值。但是,没有正式的保证
std::intptr\u t
void*
std::intptr\t
将返回原始指针值ys产生初始值。
std::intptr\u t
中可能有不同的值表示相同的指针值。但实际上,这可能不是问题。@Julius在这种情况下,使用
std::uintptr\u t
不会解决这个问题吗?它不会有为相同的值使用不同编码的问题。@C鲁兹让:不,未签名的版本也有同样的问题。让我引用7.20.1.4:“以下类型指定了一个无符号整数类型,其属性是指向
void
的任何有效指针都可以转换为该类型,然后再转换回指向
void
的指针,结果将与原始指针进行比较:
uintpttr\u t
”。请注意,只描述了此往返(而不是另一个)@Julius啊,我明白了。那么,通过
std::memcpy
进行双关黑客攻击怎么样?一个人可以
memcpy
void*
上的值,然后
memcpy
将其返回。这不会违反严格的别名,智能编译器会将其编译成
mov
指令,因此仍然有效。
int* num = (int*)fileNum;
int num = (int)fileNum;
void *pthread_func(void *_arg) {
    int arg = *(int*)_arg; // we're receiving an int
    // ...
}

int main() {
    pthread_t threads[20];
    int       args[20]; // unique arg location for each thread

    for (int i = 0; i < 20; ++i) {
        args[i] = (whatever you want to pass)

        // create the thread, give it its unique arg location
        pthread_create(&threads[i], NULL, pthread_func, &args[i]);
    }

    // ... join the threads, etc. ...
}
void *pthread_func(void *_arg) {
    int arg = (int)(intptr_t)_arg; // we're receiving an int encoded as void*
    // ...
}

int main() {
    pthread_t threads[20];

    for (int i = 0; i < 20; ++i) {
        void *arg = (void*)(intptr_t)(whatever you want to pass);

        // create the thread, give it its packed argument
        pthread_create(&threads[i], NULL, pthread_func, arg);
    }

    // ... join the threads, etc. ...
}