This is a multi-threaded program that outputs prime numbers. The user runs the program and enters a number into the command line. It creates a separate thread that outputs all the prime numbers less than or equal to the number entered by the user.
I have an error: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] I'm so close but I've been staring at this for awhile now. I thought I would get some feedback.
How can I fix this? It is referring to the void here:
(void *)count);
Here is all the code:
#include <stdio.h>
#include <pthread.h>
int N = 100; //number of promes to be generated
int prime_arr[100000] = {0}; //prime arrray
void *printprime(void *ptr) //thread function
{
int j, flag;
int i = (int)(long long int)ptr; //getting thread number
//for thread 0, we check for all primes 0,4,8,12
//for thread 1, we check for all primes 1,5,9,13
while (i < N) { //while number in range
flag = 0; //check if i has factor
for (j = 2; j <= i / 2; j ) //factor can be at max i/2 value
{
if (i % j == 0) //factor found
{
flag = 1;
break;
}
}
if (flag == 0 && (i > 1)) //prime found, no factor
{
prime_arr[i] = 1;
}
i = 4; //increase by interval of 4
}
}
int main()
{
printf("Enter N: ");
scanf("%d", &N); //input N
pthread_t tid[4] = {0}; //create an array of 4 threads
int count = 0;
for (count = 0; count < 4; count ) //initialize threads and start
{
printf("\r\n CREATING THREADS %d", count);
pthread_create(&tid[count], NULL, printprime,(void *)count); //count is passed as argument, target = printprime
}
printf("\n");
for (count = 0; count < 4; count )
{
pthread_join(tid[count], NULL); //while all thread havent finished
}
int c = 0;
for (count = 0; count < N; count ) //print primes
if (prime_arr[count] == 1)
printf("%d ", count);
printf("\n");
return 0;
}
CodePudding user response:
Use a uintptr_t or a intptr_t instead of an int.
Technically, that's for storing a pointer in an integer, not for storing an integer in a pointer. So it's not exactly kosher. But it's still a common practice.
To do it properly, you would need to (statically or dynamically) allocate a variable for each thread, and pass the address of that variable to the thread.
CodePudding user response:
Here you cast count to a void* which isn't a compatible type.
pthread_create(&tid[count], NULL, printprime, (void*) count);
And here you try to convert it back to an int improperly:
int i = (int)(long long int)ptr;
I suggest creating workpackages, tasks that you instead use and cast proberly to void* and back.
Example:
#include <pthread.h>
#include <stdio.h>
typedef struct {
pthread_t tid;
int count;
} task_t;
void *printprime(void *ptr) {
task_t *task = ptr;
task->count = 10; // do some work
return NULL;
}
#define TASKS (4)
int main() {
task_t tasks[TASKS] = {0}; // an array of tasks
for (int count = 0; count < TASKS; count) {
tasks[count].count = count; // fill the task with some job
pthread_create(&tasks[count].tid, NULL, printprime, &tasks[count]);
}
// join and take care of result from all threads
for (int count = 0; count < TASKS; count) {
pthread_join(tasks[count].tid, NULL);
printf("task %d value = %d\n", count, tasks[count].count);
}
}
