使用内存泄漏的 pthread
using pthread with memory leak
只是一个测试多线程的小程序。它应该打印出一条 'Hello' 消息,其中包含线程索引和线程位置。
我阅读了 why pthread cause memory leak 并尝试使用 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)
请注意,您正在 runMe 函数中调用 malloc。每次调用 malloc : malloc(sizeof(int))
都会分配 4 个字节的内存。您创建了 10 个线程,因此分配了 40 个字节。但是你永远不会释放这段记忆。为了释放内存,您必须在内存地址上调用 free:
int *ret = (int*)malloc(sizeof(int));
// code using ret
free(ret);
如果在使用后释放地址,就不会发生内存泄漏。
你的泄漏是因为你分配的内存没有对应的free action。
您正在使用的代码 似乎 试图将动态分配传回给调用者。正确使用 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 *)
线程程序。任何不属于那种形式的东西都是不合规的,应该避免。
只是一个测试多线程的小程序。它应该打印出一条 'Hello' 消息,其中包含线程索引和线程位置。
我阅读了 why pthread cause memory leak 并尝试使用 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)
请注意,您正在 runMe 函数中调用 malloc。每次调用 malloc : malloc(sizeof(int))
都会分配 4 个字节的内存。您创建了 10 个线程,因此分配了 40 个字节。但是你永远不会释放这段记忆。为了释放内存,您必须在内存地址上调用 free:
int *ret = (int*)malloc(sizeof(int));
// code using ret
free(ret);
如果在使用后释放地址,就不会发生内存泄漏。
你的泄漏是因为你分配的内存没有对应的free action。
您正在使用的代码 似乎 试图将动态分配传回给调用者。正确使用 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 *)
线程程序。任何不属于那种形式的东西都是不合规的,应该避免。