How to pass an int as “void *” to thread start function?












2















I originally had a global variable for my fibonacci variable array, but found out that is not allowed. I need to do elementary multithreading and handle race conditions, but I can't get past feeding an int as a void argument in pthread create. I've tried using a constant pointer with no luck. For some strange reason the void* gets past the first boolean test but not the else if:



  $ gcc -o fibonacci fibonacci.c
fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
else if (arg == 1)
~~~ ^ ~
1 warning generated.


My code is a mess and I am getting really confused because I have rewritten it so many times. If I cast all the args in my thread run function as ints I get a segmentation fault 11, which makes sense. All attempts at passing the i index by address and dereferencing it have failed, as it is a void and can't be used as an int. Can you suggest something else?



#include<stdio.h> //for printf
#include<stdlib.h> //for malloc
#include<pthread.h> //for threading

#define SIZE 25 //number of fibonaccis to be computed
int *fibResults; //array to store fibonacci results

void *run(void *arg) //executes and exits each thread
{
if (arg == 0)
{
fibResults[(int)arg] = 0;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}

else if (arg == 1)
{
fibResults[(int)arg] = 1;
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else
{
fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
}

//main function that drives the program.
int main()
{
pthread_attr_t a;
fibResults = (int*)malloc (SIZE * sizeof(int));
pthread_attr_init(&a);

for (int i = 0; i < SIZE; i++)
{
pthread_t thread;
pthread_create(&thread, &a, run,(void*) &i);
printf("Thread[%d] createdt", i);
fflush(stdout);
pthread_join(thread, NULL);
printf("Thread[%d] joined & exitedt", i);
}
return 0;
}









share|improve this question





























    2















    I originally had a global variable for my fibonacci variable array, but found out that is not allowed. I need to do elementary multithreading and handle race conditions, but I can't get past feeding an int as a void argument in pthread create. I've tried using a constant pointer with no luck. For some strange reason the void* gets past the first boolean test but not the else if:



      $ gcc -o fibonacci fibonacci.c
    fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
    else if (arg == 1)
    ~~~ ^ ~
    1 warning generated.


    My code is a mess and I am getting really confused because I have rewritten it so many times. If I cast all the args in my thread run function as ints I get a segmentation fault 11, which makes sense. All attempts at passing the i index by address and dereferencing it have failed, as it is a void and can't be used as an int. Can you suggest something else?



    #include<stdio.h> //for printf
    #include<stdlib.h> //for malloc
    #include<pthread.h> //for threading

    #define SIZE 25 //number of fibonaccis to be computed
    int *fibResults; //array to store fibonacci results

    void *run(void *arg) //executes and exits each thread
    {
    if (arg == 0)
    {
    fibResults[(int)arg] = 0;
    printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
    pthread_exit(0);
    }

    else if (arg == 1)
    {
    fibResults[(int)arg] = 1;
    printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
    pthread_exit(0);
    }
    else
    {
    fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
    printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
    pthread_exit(0);
    }
    }

    //main function that drives the program.
    int main()
    {
    pthread_attr_t a;
    fibResults = (int*)malloc (SIZE * sizeof(int));
    pthread_attr_init(&a);

    for (int i = 0; i < SIZE; i++)
    {
    pthread_t thread;
    pthread_create(&thread, &a, run,(void*) &i);
    printf("Thread[%d] createdt", i);
    fflush(stdout);
    pthread_join(thread, NULL);
    printf("Thread[%d] joined & exitedt", i);
    }
    return 0;
    }









    share|improve this question



























      2












      2








      2








      I originally had a global variable for my fibonacci variable array, but found out that is not allowed. I need to do elementary multithreading and handle race conditions, but I can't get past feeding an int as a void argument in pthread create. I've tried using a constant pointer with no luck. For some strange reason the void* gets past the first boolean test but not the else if:



        $ gcc -o fibonacci fibonacci.c
      fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
      else if (arg == 1)
      ~~~ ^ ~
      1 warning generated.


      My code is a mess and I am getting really confused because I have rewritten it so many times. If I cast all the args in my thread run function as ints I get a segmentation fault 11, which makes sense. All attempts at passing the i index by address and dereferencing it have failed, as it is a void and can't be used as an int. Can you suggest something else?



      #include<stdio.h> //for printf
      #include<stdlib.h> //for malloc
      #include<pthread.h> //for threading

      #define SIZE 25 //number of fibonaccis to be computed
      int *fibResults; //array to store fibonacci results

      void *run(void *arg) //executes and exits each thread
      {
      if (arg == 0)
      {
      fibResults[(int)arg] = 0;
      printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
      pthread_exit(0);
      }

      else if (arg == 1)
      {
      fibResults[(int)arg] = 1;
      printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
      pthread_exit(0);
      }
      else
      {
      fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
      printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
      pthread_exit(0);
      }
      }

      //main function that drives the program.
      int main()
      {
      pthread_attr_t a;
      fibResults = (int*)malloc (SIZE * sizeof(int));
      pthread_attr_init(&a);

      for (int i = 0; i < SIZE; i++)
      {
      pthread_t thread;
      pthread_create(&thread, &a, run,(void*) &i);
      printf("Thread[%d] createdt", i);
      fflush(stdout);
      pthread_join(thread, NULL);
      printf("Thread[%d] joined & exitedt", i);
      }
      return 0;
      }









      share|improve this question
















      I originally had a global variable for my fibonacci variable array, but found out that is not allowed. I need to do elementary multithreading and handle race conditions, but I can't get past feeding an int as a void argument in pthread create. I've tried using a constant pointer with no luck. For some strange reason the void* gets past the first boolean test but not the else if:



        $ gcc -o fibonacci fibonacci.c
      fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
      else if (arg == 1)
      ~~~ ^ ~
      1 warning generated.


      My code is a mess and I am getting really confused because I have rewritten it so many times. If I cast all the args in my thread run function as ints I get a segmentation fault 11, which makes sense. All attempts at passing the i index by address and dereferencing it have failed, as it is a void and can't be used as an int. Can you suggest something else?



      #include<stdio.h> //for printf
      #include<stdlib.h> //for malloc
      #include<pthread.h> //for threading

      #define SIZE 25 //number of fibonaccis to be computed
      int *fibResults; //array to store fibonacci results

      void *run(void *arg) //executes and exits each thread
      {
      if (arg == 0)
      {
      fibResults[(int)arg] = 0;
      printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
      pthread_exit(0);
      }

      else if (arg == 1)
      {
      fibResults[(int)arg] = 1;
      printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
      pthread_exit(0);
      }
      else
      {
      fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
      printf("The fibonacci of %d= %dn", (int)arg, fibResults[(int)arg]);
      pthread_exit(0);
      }
      }

      //main function that drives the program.
      int main()
      {
      pthread_attr_t a;
      fibResults = (int*)malloc (SIZE * sizeof(int));
      pthread_attr_init(&a);

      for (int i = 0; i < SIZE; i++)
      {
      pthread_t thread;
      pthread_create(&thread, &a, run,(void*) &i);
      printf("Thread[%d] createdt", i);
      fflush(stdout);
      pthread_join(thread, NULL);
      printf("Thread[%d] joined & exitedt", i);
      }
      return 0;
      }






      c casting int pthreads void






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 23 '18 at 2:10







      efuddy

















      asked Nov 23 '18 at 2:00









      efuddyefuddy

      495




      495
























          3 Answers
          3






          active

          oldest

          votes


















          1














          In the run() function you should do:



          void *run(void *ptrarg)  //executes and exits each thread
          {
          int arg = *((int *)ptrarg);
          if (arg == 0)
          ....
          ....


          and in rest of the run(), you don't need to cast the arg. Replace (int)arg with arg.



          EDIT:

          The way you are passing the argument to fun() while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.






          share|improve this answer


























          • This is wrong. OP is erroneously passing the address of i instead of the value and this produces a data race.

            – R..
            Nov 23 '18 at 3:55











          • @R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.

            – H.S.
            Nov 23 '18 at 5:44



















          5














          You don't need the cast in the call to pthread_create() — the conversion to void * is automatic.



          In the thread function, you could use



          int i = *(int *)arg;


          However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.



          So, there are various ways around that. In this context, I'd probably use



          #include <stdint.h>


          and in main():



              pthread_create(&thread, &a, run, (void*)(uintptr_t)i);


          and then in the thread function:



          int i = (uintptr_t)arg;


          Now the casts — the double cast even — is necessary. The cast to uintptr_t ensures the integer value is big enough to hold a pointer; the cast to void * is needed because there isn't an implicit cast from any integer type to void *. This ensures each thread function invocation has a different value. Sharing a pointer to an int means that everything is uncontrolled.






          share|improve this answer































            0














            @efuddy. Instead of (int)arg you should use (int *)arg to properly cast the **void pointer* void *arg






            share|improve this answer
























            • eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;

              – efuddy
              Nov 23 '18 at 2:15











            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53439834%2fhow-to-pass-an-int-as-void-to-thread-start-function%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            In the run() function you should do:



            void *run(void *ptrarg)  //executes and exits each thread
            {
            int arg = *((int *)ptrarg);
            if (arg == 0)
            ....
            ....


            and in rest of the run(), you don't need to cast the arg. Replace (int)arg with arg.



            EDIT:

            The way you are passing the argument to fun() while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.






            share|improve this answer


























            • This is wrong. OP is erroneously passing the address of i instead of the value and this produces a data race.

              – R..
              Nov 23 '18 at 3:55











            • @R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.

              – H.S.
              Nov 23 '18 at 5:44
















            1














            In the run() function you should do:



            void *run(void *ptrarg)  //executes and exits each thread
            {
            int arg = *((int *)ptrarg);
            if (arg == 0)
            ....
            ....


            and in rest of the run(), you don't need to cast the arg. Replace (int)arg with arg.



            EDIT:

            The way you are passing the argument to fun() while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.






            share|improve this answer


























            • This is wrong. OP is erroneously passing the address of i instead of the value and this produces a data race.

              – R..
              Nov 23 '18 at 3:55











            • @R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.

              – H.S.
              Nov 23 '18 at 5:44














            1












            1








            1







            In the run() function you should do:



            void *run(void *ptrarg)  //executes and exits each thread
            {
            int arg = *((int *)ptrarg);
            if (arg == 0)
            ....
            ....


            and in rest of the run(), you don't need to cast the arg. Replace (int)arg with arg.



            EDIT:

            The way you are passing the argument to fun() while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.






            share|improve this answer















            In the run() function you should do:



            void *run(void *ptrarg)  //executes and exits each thread
            {
            int arg = *((int *)ptrarg);
            if (arg == 0)
            ....
            ....


            and in rest of the run(), you don't need to cast the arg. Replace (int)arg with arg.



            EDIT:

            The way you are passing the argument to fun() while creating threads may cause race condition because all threads will be using same pointer. Check the @Jonathan's answer to avoid this problem.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 23 '18 at 5:42

























            answered Nov 23 '18 at 2:16









            H.S.H.S.

            5,5741420




            5,5741420













            • This is wrong. OP is erroneously passing the address of i instead of the value and this produces a data race.

              – R..
              Nov 23 '18 at 3:55











            • @R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.

              – H.S.
              Nov 23 '18 at 5:44



















            • This is wrong. OP is erroneously passing the address of i instead of the value and this produces a data race.

              – R..
              Nov 23 '18 at 3:55











            • @R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.

              – H.S.
              Nov 23 '18 at 5:44

















            This is wrong. OP is erroneously passing the address of i instead of the value and this produces a data race.

            – R..
            Nov 23 '18 at 3:55





            This is wrong. OP is erroneously passing the address of i instead of the value and this produces a data race.

            – R..
            Nov 23 '18 at 3:55













            @R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.

            – H.S.
            Nov 23 '18 at 5:44





            @R.. of course, in this particular case, due to the race condition situation this is not the desired way. But this is not wrong.

            – H.S.
            Nov 23 '18 at 5:44













            5














            You don't need the cast in the call to pthread_create() — the conversion to void * is automatic.



            In the thread function, you could use



            int i = *(int *)arg;


            However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.



            So, there are various ways around that. In this context, I'd probably use



            #include <stdint.h>


            and in main():



                pthread_create(&thread, &a, run, (void*)(uintptr_t)i);


            and then in the thread function:



            int i = (uintptr_t)arg;


            Now the casts — the double cast even — is necessary. The cast to uintptr_t ensures the integer value is big enough to hold a pointer; the cast to void * is needed because there isn't an implicit cast from any integer type to void *. This ensures each thread function invocation has a different value. Sharing a pointer to an int means that everything is uncontrolled.






            share|improve this answer




























              5














              You don't need the cast in the call to pthread_create() — the conversion to void * is automatic.



              In the thread function, you could use



              int i = *(int *)arg;


              However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.



              So, there are various ways around that. In this context, I'd probably use



              #include <stdint.h>


              and in main():



                  pthread_create(&thread, &a, run, (void*)(uintptr_t)i);


              and then in the thread function:



              int i = (uintptr_t)arg;


              Now the casts — the double cast even — is necessary. The cast to uintptr_t ensures the integer value is big enough to hold a pointer; the cast to void * is needed because there isn't an implicit cast from any integer type to void *. This ensures each thread function invocation has a different value. Sharing a pointer to an int means that everything is uncontrolled.






              share|improve this answer


























                5












                5








                5







                You don't need the cast in the call to pthread_create() — the conversion to void * is automatic.



                In the thread function, you could use



                int i = *(int *)arg;


                However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.



                So, there are various ways around that. In this context, I'd probably use



                #include <stdint.h>


                and in main():



                    pthread_create(&thread, &a, run, (void*)(uintptr_t)i);


                and then in the thread function:



                int i = (uintptr_t)arg;


                Now the casts — the double cast even — is necessary. The cast to uintptr_t ensures the integer value is big enough to hold a pointer; the cast to void * is needed because there isn't an implicit cast from any integer type to void *. This ensures each thread function invocation has a different value. Sharing a pointer to an int means that everything is uncontrolled.






                share|improve this answer













                You don't need the cast in the call to pthread_create() — the conversion to void * is automatic.



                In the thread function, you could use



                int i = *(int *)arg;


                However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.



                So, there are various ways around that. In this context, I'd probably use



                #include <stdint.h>


                and in main():



                    pthread_create(&thread, &a, run, (void*)(uintptr_t)i);


                and then in the thread function:



                int i = (uintptr_t)arg;


                Now the casts — the double cast even — is necessary. The cast to uintptr_t ensures the integer value is big enough to hold a pointer; the cast to void * is needed because there isn't an implicit cast from any integer type to void *. This ensures each thread function invocation has a different value. Sharing a pointer to an int means that everything is uncontrolled.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 23 '18 at 2:26









                Jonathan LefflerJonathan Leffler

                571k926851034




                571k926851034























                    0














                    @efuddy. Instead of (int)arg you should use (int *)arg to properly cast the **void pointer* void *arg






                    share|improve this answer
























                    • eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;

                      – efuddy
                      Nov 23 '18 at 2:15
















                    0














                    @efuddy. Instead of (int)arg you should use (int *)arg to properly cast the **void pointer* void *arg






                    share|improve this answer
























                    • eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;

                      – efuddy
                      Nov 23 '18 at 2:15














                    0












                    0








                    0







                    @efuddy. Instead of (int)arg you should use (int *)arg to properly cast the **void pointer* void *arg






                    share|improve this answer













                    @efuddy. Instead of (int)arg you should use (int *)arg to properly cast the **void pointer* void *arg







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 23 '18 at 2:08









                    eapetchoeapetcho

                    42727




                    42727













                    • eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;

                      – efuddy
                      Nov 23 '18 at 2:15



















                    • eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;

                      – efuddy
                      Nov 23 '18 at 2:15

















                    eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;

                    – efuddy
                    Nov 23 '18 at 2:15





                    eapetcho, thanks for the quick reply. Now I am getting: error: array subscript is not an integer fibResults[(int *)arg] = 0;

                    – efuddy
                    Nov 23 '18 at 2:15


















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53439834%2fhow-to-pass-an-int-as-void-to-thread-start-function%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    If I really need a card on my start hand, how many mulligans make sense? [duplicate]

                    Alcedinidae

                    Can an atomic nucleus contain both particles and antiparticles? [duplicate]