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)

5
  • 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? Commented Jun 22, 2015 at 8:23
  • 1
    Please post an MCVE. Try sons[i] or sons + i instead of sons + sizeof(pthread_t)*i. Also, please post the sonSimulation function. Commented Jun 22, 2015 at 8:25
  • 1
    Please see why not to cast the return value of malloc() and family in C. Commented Jun 22, 2015 at 8:25
  • This is where i declare sons pthread_t *sons = (pthread_t * ) malloc(sizeof(pthread_t)*threadNumber); Commented Jun 22, 2015 at 8:44
  • Please provide the definition of sonSimulation function or if possible the complete program. Commented Jun 22, 2015 at 8:47

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

That cast in pthread_create for the thread function argument is not needed either.
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?
@CoolGuy: "So void* can be converted to and from without a cast?" to/from any other pointer type, yes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.