I'm going to demonstrate an alternative approach, using a struct
. This alternative approach is easier to both code and maintain over time.
Your code has a few issues that might cause compiler and runtime errors, here are a few examples that should point you to the right path:
Your int
assignment isn't performing what you might have wanted or intended it to perform.
Your code assigns the numerical value of a pointer's address to an integer, probably truncating the data due to variable size differences... What you probably wanted was to store a pointer to an int.
You wrote:
int a = malloc(sizeof(int));
int b = malloc(sizeof(int));
You probably meant to write:
int * a = malloc(sizeof(int));
int * b = malloc(sizeof(int));
Your code is treating void *
as a void **
(or int *
) without using any casting...
You wrote:
int start = *((int *)args[0]);
int end = ((int *)args)[1];
You probably meant to write:
int start = ( (int *)args )[0];
int end = ( (int *)args )[1];
Your code performs malloc
three (3) times, but never calls free
(you have a memory leak).
It would be easier if you defined a struct
to contain the data you wanted to "move" to (or share with) the thread.
For example, the following untested code probably doesn't work, but it clearly show the concept of how using a struct
makes data transfer easier to manage, maintain and update. It also requires less calls to malloc
, making memory management easier.
struct ThreadData {
int start;
int end;
};
void * thread_task(void *);
int main(void) {
struct ThreadData * data = malloc(sizeof(*data));
data->start = 0;
data->end = 0; // = size;
pthread_t thr;
pthread_create(&thr, NULL, thread_task, data);
// ... do whatever.
// ... remember to join thread
}
void * thread_task(void * _data) {
struct ThreadData * data = _data;
printf("Start: %d, End: %d\n", data->start, data->end);
// remember to free the memory when you're done.
free(data);
return NULL;
}
This approach is much easier to both code and maintain. Also, when you need to add data for the new thread, it's easy - just update the struct.
You can even put complex return values back into place-holders in the struct, allowing the thread to perform more complex tasks (remember to avoid having more than a single thread writing to the same struct
field).