Michał Ziobro
Michał Ziobro

Reputation: 11762

How to properly free array of pthread_t in C?

I have array of pthread_t in C like this.

pthread_t *workers;         // worker threads running tasks from queue
workers = malloc(sizeof(pthread_t)*workers_count)

// then I creates pthread by passing &workers[i] to pthread_create() 

Now I am considering how should I free them. I done something like this:

for(int i=0; i<workers_count; i++)
        free(workers[i]);
    free(workers);

But isn't pthread_t a struct that can contain some internal pointers that should be freed? Maybe there is some function pthread_destroy(pthread_t *)?

Upvotes: 3

Views: 10764

Answers (1)

P.P
P.P

Reputation: 121397

But isn't pthread_t a struct that can contain some internal pointers that should be freed?

You don't have to worry about the what pthread_t structure contains (or if it's even a struct) or how it's implemented. You (can) only free() what you allocated using malloc(), calloc(), etc.

Maybe there is some function pthread_destroy(pthread_t *)?

There's no such function because there's no need for such a function.

So, unless you need the thread IDs later for any purpose (joining, sending signal using pthread_kill(), etc), what you do is fine. Otherwise, you need to make sure you free() at the appropriate point in your code (i.e. when the thread IDs are no longer needed).


I am not entirely sure how you allocate in your code. Here's a simple example with dynamic allocation of thread IDs which might clarify it a bit.

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

void* doSomeThing(void* arg)
{
    printf("From thread function: Thread ID: %ld\n", (long)pthread_self());
    return NULL;
}

int main(int argc, char *argv[])
{
    size_t count = 10;
    pthread_t *tid;

    tid = malloc(count * sizeof *tid);

    for(size_t i = 0; i< count; i++) {
        int rc = pthread_create(&tid[i], NULL, &doSomeThing, NULL);
        if(rc) { /* failure */ }
    }

    for(size_t i = 0;i<count; i++) {
        pthread_join(tid[i], NULL);
    }

    free(tid);
    return 0;
}

In the above example, I join with threads. Since, the thread IDs are needed for joining, I free() the tid after that.

Also, you can see I call free() just once because tid was allocated a block for 10 pthread_t's. Basically, you call free() once for each call to malloc() (or calloc() or realloc()) and the the pointer you pass to free() must be the same that was previously returned by one of the *alloc() functions.

Upvotes: 5

Related Questions