簡體   English   中英

在內存泄漏中使用pthread

[英]using pthread with memory leak

只是一個測試多線程的小程序。 它應該打印出帶有線程索引和線程位置的“ Hello”消息。

我讀了為什么pthread導致內存泄漏並嘗試使用pthread_join 似乎仍然存在內存泄漏

以下是我的代碼:

#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);

}

以下是運行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)

您的泄漏是因為分配的內存沒有相應的空閑操作。

您正在使用的代碼似乎正在嘗試將動態分配傳遞回調用方。 正確使用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);
}

輸出 (可變)

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

我還自由修復了您使用的錯誤,不兼容的功能簽名。 pthread_create 需要以下形式:

void *proc(void *)

用於線程過程。 任何形式都不符合要求的東西,應該避免。

請注意,您正在runMe函數中調用malloc。 每個對malloc的調用: malloc(sizeof(int))分配4個字節的內存。 您創建10個線程,因此分配了40個字節。 但是您永遠不會釋放此記憶。 為了釋放內存,必須在內存地址上調用free:

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

如果您在使用完地址后將其釋放,則不會有內存泄漏。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM