I'm getting a seg fault within this code, but I can't find the problem anywhere. It compiles just fine with -lpthread, but it just won't run. This program takes in an integer from the command line and then creates a new thread to calculate the collatz conjecture using that value. This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void print_con();
void calc_con(int *n);
int * values[1000];
int main(int argc, char * argv[])
{
int* num;
*num = 15;
pthread_t thread;
pthread_create(&thread,(pthread_attr_t*)NULL, (void *)&calc_con, (void *)num);
pthread_join(thread, NULL);
print_con();
return 0;
}
void calc_con(int *n)
{
int i = 0;
int * x;
*x = *n;
*values[0] = *x;
while(*x > 1)
{
if(*x % 2 == 0)
*x /= 2;
else if(*x % 2 == 1)
{
*x *= 3;
*x++;
}
i++;
*values[i] = *x;
}
pthread_exit(0);
}
void print_con()
{
int i;
for(i = 0; i < 1000; i++)
{
if(*values[i] > 0)
printf("%d", *values[i]);
}
}
okay you need to pass a void *
as an argument to pthread_create
, but you still need to respect the basics:
int* num;
*num = 15;
pthread_t thread;
pthread_create(&thread,(pthread_attr_t*)NULL, (void *)&calc_con, (void *)num);
Here *num = 15;
you're writing 15
to an uninitialized pointer . That's undefined behaviour .
I would do:
int num = 15;
pthread_t thread;
pthread_create(&thread,(pthread_attr_t*)NULL, &calc_con, &num);
note that you don't have to cast to void *
from pointers on non-void. Since num
is declared in the main
routine, you can pass a pointer on it to your threads safely.
note that as pointed by dasblinkenlight, you also have to fix the recieving end, in calc_con
, which has the same issue:
int * x; // uninitialized pointer
*x = *n; // copy data "in the woods"
just dereference into a local variable and you have your value:
int x = *((int *)n);
and another one:
int * values[1000];
is an uninitialized array of integer pointers, not an array of integers like you're intending. It should be
int values[1000];
then
values[0] = x;
(it's not because there's a lot of *
operators that it's good code)
You are passing an int
to your thread using a void*
. This will work on many platforms, but there is no guarantees that the number would "round-trip" correctly. Once you get pointer back, you save it in a dereferenced uninitialized pointer, which is incorrect.
Pass a pointer to num
instead, and copy the pointer into x
directly:
void calc_con(void *n);
...
void calc_con(void *n) {
int i = 0;
int * x = n;
*values[0] = *x;
while(*x > 1) {
if(*x % 2 == 0) {
*x /= 2;
} else if(*x % 2 == 1) {
*x *= 3;
*x++;
}
i++;
*values[i] = *x;
}
pthread_exit(0);
}
...
int num = 15;
pthread_create(&thread,(pthread_attr_t*)NULL, calc_con, (void *)&num);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.