简体   繁体   中英

using pthread with memory leak

Just a small program to test multi-threading. It supposed to print out a 'Hello' message with the index of the thread and the thread location.

I read why pthread cause memory leak and tried to use pthread_join . It seems that the memory leak still remains

Following is my code:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

void runMe(int *arg) {
    printf("Hello %d from %x\n", *arg, (unsigned int)pthread_self());
    int *ret = (int*)malloc(sizeof(int));
    *ret = *arg + 4; // note this value '4' will be different in the quiz!

    pthread_exit((void*)ret);
}

int run_threads(int n) {
    pthread_t thr[n];
    int thr_args[n];
    int *ptr = 0;
    int total = 0;

    for (int i=0; i<n; i++) {
        thr_args[i] = i;
        pthread_create(&thr[i], NULL, (void*)runMe, &thr_args[i]);

    }
    for (int j=0; j<n; j++) {
        pthread_join(thr[j], (void*)ptr++);
        total += thr_args[j];
    }
    return total;
}

int main() {

    run_threads(10);

}

Following is the result of running valgrind :

==10292== 
==10292== HEAP SUMMARY:
==10292==     in use at exit: 1,654 bytes in 14 blocks
==10292==   total heap usage: 26 allocs, 12 frees, 5,454 bytes allocated
==10292== 
==10292== LEAK SUMMARY:
==10292==    definitely lost: 40 bytes in 10 blocks
==10292==    indirectly lost: 0 bytes in 0 blocks
==10292==      possibly lost: 0 bytes in 0 blocks
==10292==    still reachable: 1,614 bytes in 4 blocks
==10292==         suppressed: 0 bytes in 0 blocks
==10292== Rerun with --leak-check=full to see details of leaked memory
==10292== 
==10292== For counts of detected and suppressed errors, rerun with: -v
==10292== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Your leak is because the memory you allocate has no corresponding free action.

The code you're using appears to be trying to convey a dynamic allocation back to the caller. Proper use of pthread_join and its second parameter can recoup that memory pointer, which can then be properly freed.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

void* runMe(void *pv)
{
    int *arg = pv;
    printf("Hello %d from %x\n", *arg, (unsigned int)pthread_self());
    int *ret = malloc( sizeof *ret );
    *ret = *arg + 4; // note this value '4' will be different in the quiz!
    return ret;
}

int run_threads(int n) {
    pthread_t thr[n];
    int thr_args[n];
    int total = 0;

    for (int i=0; i<n; i++) {
        thr_args[i] = i;
        pthread_create(thr+i, NULL, runMe, thr_args+i);

    }
    for (int j=0; j<n; j++)
    {
        // reap pointer from resulting thread.
        void *res = NULL;
        pthread_join(thr[j], &res);

        int *ires = res;
        printf("ires = %p; *ires = %d\n", ires, *ires);
        free(ires);

        total += thr_args[j];
    }
    return total;
}

int main()
{
    run_threads(10);
}

Output (varies)

Hello 9 from b0a71000
Hello 0 from b05df000
Hello 7 from b096d000
Hello 2 from b06e3000
Hello 1 from b0661000
Hello 4 from b07e7000
Hello 3 from b0765000
Hello 5 from b0869000
Hello 6 from b08eb000
Hello 8 from b09ef000
ires = 0x600000; *ires = 4
ires = 0x2009e0; *ires = 5
ires = 0x600010; *ires = 6
ires = 0x500010; *ires = 7
ires = 0x2009f0; *ires = 8
ires = 0x2012c0; *ires = 9
ires = 0x600020; *ires = 10
ires = 0x400040; *ires = 11
ires = 0x400050; *ires = 12
ires = 0x500000; *ires = 13

I also took liberty to fix your incorrect, non-compliant function signature you were using. pthread_create requires the form:

void *proc(void *)

for the thread procedure. Anything not of that form isn't compliant, and should be avoided.

Notice that you are calling malloc in the runMe function. Each call to malloc : malloc(sizeof(int)) allocates 4 bytes of memory. You make 10 threads, so 40 bytes are allocated. But you never free this memory. In order to free the memory, you must call free on the memory address:

int *ret = (int*)malloc(sizeof(int));
// code using ret
free(ret);

If you free the addresses after using them, you will have no memory leaks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM