-1

I'm trying to overwrite the value of the next item in the array with the value taked as argument in the function TaskCode by accessing it from its memory address. I have tried a lot of combinations, but it does not work as I am expecting.

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    #define NUM_THREADS 5
    
    void* TaskCode(void* argument) {
        int tid = *((int*)argument); //set tid to value of thread
        tid++;  // go to next memory address of thread_args
        tid = *((int*)argument); // set that value to the value of argument
        printf("\nI have the value: \" %d \" and address: %p! \n", tid, &tid);
        return NULL;
    }
    
    int main(int argc, char* argv[]) 
    {
        pthread_t threads[NUM_THREADS]; // array of 5 threads
        int thread_args[NUM_THREADS +1 ];   // array of 6 integers
        int rc, i;
    
            for (i = 0; i < NUM_THREADS; ++i) {/* create all threads */
                thread_args[i] = i; // set the value thread_args[i] to 0,1...,4
                printf("In main: creating thread %d\n", i);
                rc = pthread_create(&threads[i], NULL, TaskCode,
                    (void*)&thread_args[i]);
                assert(0 == rc);
            }
        /* wait for all threads to complete */
        for (i = 0; i < NUM_THREADS; ++i) {
            rc = pthread_join(threads[i], NULL);
            assert(0 == rc);
        }
        exit(EXIT_SUCCESS);
    }
Mylo
  • 3
  • 2
  • `int tid = ...;` and `tid++` and `tid = ...` is just working on the plain integer value in `tid`. It doesn't do anything with addresses or locations. To do what you want, look at `argument` instead, and where it points. And think of it as a pointer to the first element of an *array*. Now think about how to get the second element of the array (and also think about that the array itself perhaps isn't fully initialized when the thread runs, and may contain *indeterminate* values!) – Some programmer dude May 03 '21 at 18:21
  • do you mean by direct adding to the first element of the array? like ((void*) argument +1). about the last point (not fully initialized array) i'm not sure how i can deal with it. I have some experience with containers and friendly structures, but i'm not a good friend of raw types and memory managment :/ – Mylo May 03 '21 at 18:34
  • `I have tried a lot of combinations` that would be wrong approach to learning C. You need a structured learning, for example, a good book. – SergeyA May 03 '21 at 18:34
  • @SergeyA : is easy to say "you need more structure". I know i do. You can maybe suggest a particular good book. That would be a constructive comment ;) – Mylo May 03 '21 at 20:07
  • @Mylo https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list – SergeyA May 03 '21 at 20:17

1 Answers1

0

In your thread function, tid is the value of a particular member of the thread_args array in main. Any change to this variable is not reflected elsewhere.

Rather than dereferencing the converted argument right away, take it directly as a int *. Then you can do pointer arithmetic on it and further dereference it.

void* TaskCode(void* argument) {
    int *tid = argument;
    tid++;
    *tid = *((int*)argument);
    printf("\nI have the value: \" %d \" and address: %p! \n", *tid, (void *)tid);
    return NULL;
}
dbush
  • 205,898
  • 23
  • 218
  • 273
  • After the initial initialization of `tid` one could just do `tid[1] = tid[0]`. And no matter which method is used, it all requires that the next "element" is actually initialized, which is not guaranteed in the code in the question (especially since `thread_args[NUM_THREADS]` will *never* be initialized, but still used). – Some programmer dude May 03 '21 at 18:43
  • This does not compiles :/ Threads.cpp:10:21: error: invalid conversion from ‘void*’ to ‘int*’ [-fpermissive] 10 | int *tid = argument; //set tid to value of thread | ^~~~~~~~ | | | void* – Mylo May 03 '21 at 19:39
  • @Mylo To me that indicates that you're not programming in C but rather C++. In C `void *` is implicitly convertible to any other pointer type without a cast. – Some programmer dude May 03 '21 at 19:42
  • @Someprogrammerdude thanks, i had actually save my file as .cpp, i didn't see the difference until now. now i changed it to .c – Mylo May 03 '21 at 19:49