Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting int function to void*

I have a problem with casting returned integer value to void pointer. Have tried some options from this site but my problem seems to still haven't been resolved. Although the program compiles with no code errors I'm getting a segmentation fault. Am I blind and are there some mistakes in my code?

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

int ackermann(int a, int b)
{
    if(a==0)
        return a+1;
    else if(a>0 && b==0)
    {
        return ackermann(a-1, 1);
    }
    else if(a>0 && b>0)
    {
        return ackermann(a-1,ackermann(a,(b-1)));
    }
}

int main(int argc, char* argv[])
{
    int a = atoi(argv[1]);
    int b = atoi(argv[2]);
    int c = ackermann(a,b);
    void *ptr = &c;
    pthread_t mythread;
    if(pthread_create(&mythread, NULL, ptr, NULL))
    {
        printf("Could not create a thread\n");
    }

    pthread_exit(NULL);
    return 0;
}
like image 436
Michał Habigier Avatar asked Dec 17 '25 16:12

Michał Habigier


1 Answers

As was mentioned in the comments, you're not actually calling the function ackermann in a separate thread. What you are doing is calling the function directly from main, storing the result in an int, and passing a pointer to that int as the third parameter to pthread_create, which is supposed to be a pointer to the function to run.

Right now, ackermann does not have the appropriate signature to be passed to pthread_create. A function that starts a new thread should be declared like this:

void *my_thread_function(void *parameter);

Given that ackermann is called recursively, it would be cleaner to pass a a wrapper function to pthread_create and have that wrapper call ackermann rather than modifying ackermann to match the above signature.

Because you need to pass multiple parameters to your thread function, you'll need to create a struct which contains all the parameters and pass a pointer to that struct to thread function.

You can also store the return value in this struct so that the function which started the thread has access to it.

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

int ackermann(int a, int b)
{
    if(a==0) {
        return a+1;
    } else if(a>0 && b==0) {
        return ackermann(a-1, 1);
    } else if(a>0 && b>0) {
        return ackermann(a-1,ackermann(a,(b-1)));
    }
    // if none of the above conditions are true, no value is returned
    // better check for this
}

struct ackermann_params {
    int a;
    int b;
    int result;
};

void *ackermann_thr(void *arg)
{
    struct ackermann_params *params = arg;
    params->result = ackermann(params->a, params->b);
    return NULL;
}

int main(int argc, char* argv[])
{
    struct ackermann_params params;
    if (argc < 3) {
        printf("invalid number of arguments\n");
        exit(1);
    }
    params.a = atoi(argv[1]);
    params.b = atoi(argv[2]);
    pthread_t mythread;
    if(pthread_create(&mythread, NULL, ackermann_thr, &params))
    {
        perror("Could not create a thread\n");
        exit(1);
    }
    if (pthread_join(mythread, NULL)) {
        perror("join failed\n");
        exit(1);
    }
    printf("result=%d\n", params.result);

    return 0;
}
like image 122
dbush Avatar answered Dec 19 '25 06:12

dbush



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!