C- Valgrind,总堆的使用量不断增加



请以下面的示例为例。看来没有内存泄漏,但是为什么分配的总堆用法和字节不断增加呢?如果我删除第一部分(test1),valgrind结果不会显示出任何增加的堆,并且始终总堆的用法:1个Allocs,1 Frees,568字节分配

代码示例:

int main(void)
{
    while(1)
    {
        FILE *test1;
        test1 = fopen("test1", "w");
        fprintf(test1, "somethingn");
        fclose(test1);
        pid_t childPid; 
        childPid = fork();
        if(childPid == 0)
        {
            int j;
            FILE *test2;
            test2 = fopen("test2", "w");
            for(j = 0; j < 4; j++)
            {
                fprintf(test2, "somethingn");
            }
            fclose(test2);
            exit(0);
        }
        else 
        {    
             int returnStatus;    
             waitpid(childPid, &returnStatus, 0);
        }   
        sleep(2);
    }
    return 0;
}

valgrind结果:

==6314== Memcheck, a memory error detector
==6314== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6314== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==6314== Command: ./test
==6314== Parent PID: 6313
==6314== 
==6315== 
==6315== HEAP SUMMARY:
==6315==     in use at exit: 0 bytes in 0 blocks
==6315==   total heap usage: 2 allocs, 2 frees, 1,136 bytes allocated
==6315== 
==6315== All heap blocks were freed -- no leaks are possible
==6315== 
==6315== For counts of detected and suppressed errors, rerun with: -v
==6315== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==6317== 
==6317== HEAP SUMMARY:
==6317==     in use at exit: 0 bytes in 0 blocks
==6317==   total heap usage: 3 allocs, 3 frees, 1,704 bytes allocated
==6317== 
==6317== All heap blocks were freed -- no leaks are possible
==6317== 
==6317== For counts of detected and suppressed errors, rerun with: -v
==6317== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==6319== 
==6319== HEAP SUMMARY:
==6319==     in use at exit: 0 bytes in 0 blocks
==6319==   total heap usage: 4 allocs, 4 frees, 2,272 bytes allocated
==6319== 
==6319== All heap blocks were freed -- no leaks are possible
==6319== 
==6319== For counts of detected and suppressed errors, rerun with: -v
==6319== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

使用MassIF如下所述,我们会为程序提供有关堆的输出。我像这样用了

valgrind --tool=massif ./a.out

然后,在massif的输出文件中(每个子过程也一个),我们可以看到这样的行:

[...]
#-----------
snapshot=3
#-----------
time=115870
mem_heap_B=4648
mem_heap_extra_B=24
mem_stacks_B=0
heap_tree=peak
n2: 4648 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
 n1: 4096 0x4E9F380: _IO_file_doallocate (filedoalloc.c:101)
  n1: 4096 0x4EAE874: _IO_doallocbuf (genops.c:398)
   n1: 4096 0x4EADA46: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:828)
    n1: 4096 0x4EAC11B: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1339)
     n1: 4096 0x4EA0A79: fwrite (iofwrite.c:39)
      n0: 4096 0x1088E5: main (in /home/.../a.out)
 n1: 552 0x4E9FF2B: __fopen_internal (iofopen.c:69)
  n0: 552 0x1088C4: main (in /home/.../a.out)
[...]

在这里,我们看到与文件操作相关的各种库功能(fileops.c)为您的FILE S分配内存(此处显示的fwrite)。

当您评论test1部分时,为什么分配不会增加?

好吧,如果您评论该部分,则删除在循环的每个运行中运行的代码部分。剩下的代码仅在子过程中运行,这意味着总的内存分配(和分配计数)在父进程中保持恒定为0。所有孩子都将进行相同的操作,从而导致相同数量的分配。


通常,标准库中使用的C代码有时需要内存来完成他们需要做的事情。文件功能需要缓冲区空间来存储字节以读取/写入,因为文件在较低级别的磁盘块读取,等等。

另外,从 fclose的人页面:

fclose()函数通过流汇总流的流(使用fflush(3)编写任何缓冲输出数据)并关闭基础文件描述符。

在这里引用了一些缓冲数据,当您致电fclose

时,这些缓冲区也将被释放。

最新更新