3

I am have an issue with freeing my allocated memory, and it seems that my inexperience has lead me to this fatal error.

Below I have a simple code:

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

void *thread(void *arg) {
    return NULL;
}

int main() {
    pthread_t id;
    pthread_t *pid = malloc(10 * (sizeof(pthread_t)));
    for (int i = 0; i < 10; i++) {
        pthread_create(&id, NULL, thread, NULL);
        pid[i] = id;
    }
    free(pid); 
}

So, apprently free(pid) does not free the 10 threads I created as well and as a result valgrind is telling me that I only free 1 out of 11 allocs. how do I go about free the 10 threads?

EDIT: I think I need to store the address of the 10 threads and then free those in a for loop if I am correct here?

EDIT#2:

I have tried the following:

  for (int i = 0; i < 10; i++) {
      free(pid[i]);
  } 

but I get this error

/usr/include/stdlib.h:483:13: note: expected ‘void *’ but argument is of type ‘pthread_t’
 extern void free (void *__ptr) __THROW;
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Belphegor
  • 1,683
  • 4
  • 23
  • 44

2 Answers2

3

pthread_create will internally allocate some memory. If the main thread just exits it does not allow the created threads the opportunity to clean up. And hence some allocated memory remains not freed at the program exit time. That is what valgrind is picking up. To fix that, ensure the main thread waits for all the threads to exit by calling pthread_join before the free(pid) call:

for(int i=0; i<10; i++) {
    pthread_join(pid[i], NULL);
}
kaylum
  • 13,833
  • 2
  • 22
  • 31
2

The extra malloc()s are used by pthread_create(). You'll need to wait for your threads to die for them to be freed, for instance with pthread_join(). You must not call free() on them.

For instance:

#define _POSIX_C_SOURCE 200809L

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

void* thread(void* arg)
{
    return NULL;
}

int main(){
    pthread_t id;
    pthread_t *pid = malloc(10 *(sizeof(pthread_t)));
    for(int i=0; i<10; i++) {
        pthread_create(&id, NULL, thread, NULL);
        pid[i] = id;
        pthread_join(id, NULL);
    }

    free(pid); 
}
Crowman
  • 25,242
  • 5
  • 48
  • 56
  • this answer results in only one thread running at any one time. probably not what the OP wants. – user3629249 Mar 14 '16 at 00:39
  • 1
    @user3629249: Having a thread function that does nothing is probably not what the OP wants, either. The point of the question is to understand what's happening with the `malloc()`s and Valgrind, not to write a sensible threaded program. – Crowman Mar 14 '16 at 00:40