简体   繁体   English

在内存泄漏中使用pthread

[英]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. 它应该打印出带有线程索引和线程位置的“ Hello”消息。

I read why pthread cause memory leak and tried to use pthread_join . 我读了为什么pthread导致内存泄漏并尝试使用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 : 以下是运行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. 正确使用pthread_join及其第二个参数可以收回该内存指针,然后可以正确释放该内存指针。

#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: pthread_create 需要以下形式:

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. 请注意,您正在runMe函数中调用malloc。 Each call to malloc : malloc(sizeof(int)) allocates 4 bytes of memory. 每个对malloc的调用: malloc(sizeof(int))分配4个字节的内存。 You make 10 threads, so 40 bytes are allocated. 您创建10个线程,因此分配了40个字节。 But you never free this memory. 但是您永远不会释放此记忆。 In order to free the memory, you must call free on the memory address: 为了释放内存,必须在内存地址上调用free:

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. 如果您在使用完地址后将其释放,则不会有内存泄漏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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