C++ 如何通过函数的void指针参数传递int值并将其转换回int值?
我正在尝试创建一个多线程程序,该程序为获取它的每个文件(file1.txt到file20.txt)创建一个线程,我需要使用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
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创建< /代码>调用警告。ngepthread_create(&tids[i],NULL,getSales,(void*)i);
topthread_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. ...
}