我创建了一个线程数组,但我没有使用它们。结果是内存泄漏。有什么功能可以用来释放内存吗?
void func( args... )
{
.
.
.
pthread_t threads[10]
int i;
for( i = 0; i < 8; i++ )
{
/* create 8 threads */
}
for( i = 0; i < 8; i++ )
{
/* join 8 threads */
}
.
.
.
return;
}
我用于实验的代码就在这里。我让它使用比我想要的更多的线程。如果我不添加10个以上的线程,根本就没有泄漏。它需要一些文本文件作为参数 使用
编译和运行gcc -g -Wall -pthread test.c valgrind --tool = memcheck --leak-check = full --show-reachable = yes ./a.out * .txt
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#define DEBUG 0
#define BUFLEN 10000
/* function declaration */
static void* countLines(void* input);
static void error(const char*);
/* global variable */
static int total_th; /* total number of threads */
static int count_th; /* the count of the finished threads */
/*
* main starts here
*/
int main(int argc, char** argv)
{
/* if there is no command line arguments, print error */
if(argc < 2)
{
error("there should be at lease one argument!\n");
exit(-1);
}
/* initialize thread counters */
total_th = argc - 1;
count_th = 0;
pthread_t pt[ total_th + 10]; /* the ptreads to read file lines */
/* create threads for each file */
int i;
for(i = 0; i < total_th; i++)
{
if((pthread_create(&pt[i], NULL,
countLines, (void*) argv[i + 1])) != 0)
{
fprintf(stderr, "error in thread create\n");
}
}
/* main thread wait for all the slaves to finish */
for(i = 0; i < total_th; i++)
{
if(pthread_join(pt[i], NULL) != 0)
fprintf(stderr, "error in thread join\n");
}
return(0);
}
/**
* void* countLines(void * input)
* @param input: the name of the file
* @return NULL
* count the number of lines for the specified file
*/
void* countLines(void * input)
{
char* fileName = (char*) input; /* file name */
int newLineCount = 0; /* a count of the new line character */
int fd; /*file descriptor*/
/* open file, if open fail print error message */
if((fd = open(fileName, O_RDONLY)) == -1)
{
fprintf(stderr, "Can not open file - %s\n", fileName);
count_th++;
return NULL;
}
char buf[BUFLEN]; /* the buffer to be read */
int lastRead; /* the number of characters read to buffer */
/* read the file */
while((lastRead = read(fd, buf, BUFLEN)))
{
/* detect error state */
if(lastRead == -1)
{
fprintf(stderr, "error reading file %s!\n", fileName);
count_th++;
return NULL;
}
/* count the new line character */
int i;
for(i = 0; i < lastRead; i++)
{
if(buf[i] == '\n')
{
newLineCount++;
}
}
}
printf("There are %d lines in %s\n", newLineCount, fileName);
close(fd); /* close file descriptor */
pthread_exit( NULL );
}
/**
* void error(const char*str )
* @param str error message
* print an error message
*/
void error(const char *str)
{
perror(str);
exit(-1);
}
这是我运行程序时valgrind打印的内容。内存泄漏来自我创建未使用线程的函数。 有些人会打印这条消息,有时则没有。
==4737==
==4737== HEAP SUMMARY:
==4737== in use at exit: 1,590 bytes in 5 blocks
==4737== total heap usage: 12 allocs, 7 frees, 3,494 bytes allocated
==4737==
==4737== 36 bytes in 1 blocks are still reachable in loss record 1 of 5
==4737== at 0x4C28F9F: malloc (vg_replace_malloc.c:236)
==4737== by 0x40085BF: _dl_map_object (dl-load.c:162)
==4737== by 0x4012B79: dl_open_worker (dl-open.c:226)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x40133A9: _dl_open (dl-open.c:569)
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47)
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53)
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==4737== by 0x4E3D9DF: __pthread_unwind (unwind.c:130)
==4737== by 0x4E380A4: pthread_exit (pthreadP.h:265)
==4737==
==4737== 36 bytes in 1 blocks are still reachable in loss record 2 of 5
==4737== at 0x4C28F9F: malloc (vg_replace_malloc.c:236)
==4737== by 0x400B43C: _dl_new_object (dl-object.c:164)
==4737== by 0x4006575: _dl_map_object_from_fd (dl-load.c:967)
==4737== by 0x400831E: _dl_map_object (dl-load.c:2260)
==4737== by 0x4012B79: dl_open_worker (dl-open.c:226)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x40133A9: _dl_open (dl-open.c:569)
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47)
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53)
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==4737==
==4737== 56 bytes in 1 blocks are still reachable in loss record 3 of 5
==4737== at 0x4C28F9F: malloc (vg_replace_malloc.c:236)
==4737== by 0x400D187: _dl_map_object_deps (dl-deps.c:505)
==4737== by 0x4012BD6: dl_open_worker (dl-open.c:263)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x40133A9: _dl_open (dl-open.c:569)
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47)
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53)
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==4737== by 0x4E3D9DF: __pthread_unwind (unwind.c:130)
==4737== by 0x4E380A4: pthread_exit (pthreadP.h:265)
==4737==
==4737== 288 bytes in 1 blocks are still reachable in loss record 4 of 5
==4737== at 0x4C279F2: calloc (vg_replace_malloc.c:467)
==4737== by 0x4010359: _dl_check_map_versions (dl-version.c:300)
==4737== by 0x4012EF0: dl_open_worker (dl-open.c:269)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x40133A9: _dl_open (dl-open.c:569)
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47)
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53)
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==4737== by 0x4E3D9DF: __pthread_unwind (unwind.c:130)
==4737== by 0x4E380A4: pthread_exit (pthreadP.h:265)
==4737==
==4737== 1,174 bytes in 1 blocks are still reachable in loss record 5 of 5
==4737== at 0x4C279F2: calloc (vg_replace_malloc.c:467)
==4737== by 0x400B1CD: _dl_new_object (dl-object.c:77)
==4737== by 0x4006575: _dl_map_object_from_fd (dl-load.c:967)
==4737== by 0x400831E: _dl_map_object (dl-load.c:2260)
==4737== by 0x4012B79: dl_open_worker (dl-open.c:226)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x40133A9: _dl_open (dl-open.c:569)
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86)
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47)
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53)
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==4737==
==4737== LEAK SUMMARY:
==4737== definitely lost: 0 bytes in 0 blocks
==4737== indirectly lost: 0 bytes in 0 blocks
==4737== possibly lost: 0 bytes in 0 blocks
==4737== still reachable: 1,590 bytes in 5 blocks
==4737== suppressed: 0 bytes in 0 blocks
==4737==
==4737== For counts of detected and suppressed errors, rerun with: -v
==4737== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
答案 0 :(得分:2)
使用pthread_exit
的“问题”。 This question提供了一些细节,特别是:
几个glibc函数在第一次调用malloc()时分配内存,它们在进程生命周期的剩余时间内保持分配。 glibc并不打算在进程退出时释放这个内存,因为它知道该进程正在被拆除 - 它只是浪费CPU周期。
所以这个内存泄漏很好。
但是,要真正摆脱valgrind消息,您可以在return NULL;
的最后一行使用pthread_exit(NULL);
代替countLines
,因为您刚刚从启动例程返回