1

I have a problem with pthread_create. In this test, I create an array of integers, and then try to use them as parameters for a function that must be executed into a thread.

This is where I create the indexes:

int *indexes = (int *) malloc(sizeof(int)*threadNumber);
int i;
for (i = 0; i < threadNumber; i++){
    indexes[i] = i;
}

And this is where I create threads:

int i;
for (i = 0; i < threadNumber; i++){
    printf("%i %i    ", i, indexes[i]);
}
for (i = 0; i < threadNumber; i++){
    printf("%i %i    ", i, indexes[i]);
    pthread_create(sons + sizeof(pthread_t)*i, NULL, sonSimulation, (void *) &indexes[i]);
}

The first printf prints the following:

0 0   1 1   2 2   3 3   4 4

The second one, which is supposed to print the same output, prints this:

0 0   1 1   2 2   3 3   4 23154684

The last number changes each time I executes the code. I'm not able to fix this. Any suggestion?

(sonSimulation just prints the parameter)

Luca
  • 23
  • 2
  • 2
    What is `sons`? How is it declared? Why don't you use plain array indexing for it? Also, you're threads doesn't overwrite the pointer they get? – Some programmer dude Jun 22 '15 at 08:23
  • 1
    Please post an [MCVE](http://stackoverflow.com/help/mcve). Try `sons[i]` or `sons + i` instead of `sons + sizeof(pthread_t)*i`. Also, please post the `sonSimulation` function. – Spikatrix Jun 22 '15 at 08:25
  • 1
    Please [see why not to cast](http://stackoverflow.com/q/605845/2173917) the return value of `malloc()` and family in `C`. – Sourav Ghosh Jun 22 '15 at 08:25
  • This is where i declare sons pthread_t *sons = (pthread_t * ) malloc(sizeof(pthread_t)*threadNumber); – Luca Jun 22 '15 at 08:44
  • Please provide the definition of sonSimulation function or if possible the complete program. – Rndp13 Jun 22 '15 at 08:47

1 Answers1

4

There is a problem here:

pthread_create(sons + sizeof(pthread_t)*i, NULL, sonSimulation, (void *) &indexes[i]);

You allocate sons using

pthread_t *sons = (pthread_t * ) malloc(sizeof(pthread_t)*threadNumber);

So, sons + sizeof(pthread_t)*i in the pthread_create is wrong. When you use sons+i, it automatically moves the sons pointer sizeof(pthread_t) bytes forward because of pointer arithmetic. Using sons + sizeof(pthread_t)*i moves the pointer into invalid memory locations invoking Undefined Behavior.

To fix the problem, use

pthread_create(sons + i, NULL, sonSimulation, (void *) &indexes[i]);

or

pthread_create(&sons[i], NULL, sonSimulation, (void *) &indexes[i]);

instead of

pthread_create(sons + sizeof(pthread_t)*i, NULL, sonSimulation, (void *) &indexes[i]);

Also, as pointed out in the comments, you need not cast the result of malloc(and family) in C.
The void* cast in the last argument of is not needed either as @JoachimPileborg comments.

Community
  • 1
  • 1
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
  • That cast in `pthread_create` for the thread function argument is not needed either. – Some programmer dude Jun 22 '15 at 09:04
  • I thought that `void*` can be converted to any other type without a cast, but the opposite needs a cast. So `void*` can be converted to and from without a cast? – Spikatrix Jun 22 '15 at 09:10
  • @CoolGuy: "*So `void*` can be converted to and from without a cast?*" to/from any other pointer type, yes. – alk Jun 22 '15 at 11:11