我一直在用valgrind运行此代码,并且valgrind显示没有内存泄漏,尽管我没有关闭fd_read,为什么?
编辑:
这个问题出现在我的一项考试中,据我的教授说,正确的答案是该程序存在内存泄漏。文件描述符泄漏被认为是内存泄漏?
QuickFilterOption
答案 0 :(得分:3)
调用open
,pipe
或dup
来“分配”低级整数文件描述符不会分配任何用户内存,因此,如果它们不构成任何内存泄漏,重新关闭。
现在,可以这么说,该程序可以说是“泄漏”了文件描述符,这是另一种资源泄漏,这在长时间运行的程序中可能是一个问题,尽管由于某种原因它通常不会最终终止在实践中几乎是一个大问题。
(当然,在任何理智的操作系统下,打开文件描述符都会在退出时最终关闭,就像仍然有效但最终释放了仍然分配的内存一样。几乎没有人担心非长期运行的程序上的fd泄漏)
答案 1 :(得分:2)
在这种情况下,不会泄漏内存,主要是因为open是此处的系统调用。如果有泄漏,valgrind仍会指出它们。
也就是说,打开文件可能在低级库中分配了内存(例如,您称fopen而不是open),主要是为了在文件本身上存储“句柄”。
最后,在通常的OS上,内核能够关闭您可能打开的文件,并取回您可能忘记退出时释放的内存,因此有人可能会怀疑谁在乎。通常认为,即使最后没有真正的危害,也不要在离开前清理东西。这是一种不好的做法。
您可以使用以下方法跟踪未关闭的文件:
valgrind --track-fds=yes ./a.out
以您的情况我会得到:
==30758== Memcheck, a memory error detector
==30758== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==30758== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==30758== Command: ./a.out
==30758==
==30758==
==30758== FILE DESCRIPTORS: 7 open at exit.
==30758== Open file descriptor 1:
==30758== at 0x4F26637: dup (in /usr/lib64/libc-2.27.so)
==30758== by 0x4006A9: main (in a.out)
==30758==
==30758== Open file descriptor 3:
==30758== at 0x4F266C7: pipe (in /usr/lib64/libc-2.27.so)
==30758== by 0x400670: main (in a.out)
==30758==
==30758== Open file descriptor 38: /usr/share/applications/org.kde.akonadiimportwizard.desktop
==30758== <inherited from parent>
==30758==
==30758== Open file descriptor 27:
==30758== <inherited from parent>
==30758==
==30758== Open file descriptor 26:
==30758== <inherited from parent>
==30758==
==30758== Open file descriptor 2: /dev/pts/16
==30758== <inherited from parent>
==30758==
==30758== Open file descriptor 0: /dev/pts/16
==30758== <inherited from parent>
==30758==
==30758==
==30758== HEAP SUMMARY:
==30758== in use at exit: 0 bytes in 0 blocks
==30758== total heap usage: 1 allocs, 1 frees, 4,096 bytes allocated
==30758==
==30758== All heap blocks were freed -- no leaks are possible
==30758==
==30758== For counts of detected and suppressed errors, rerun with: -v
==30758== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
答案 2 :(得分:1)
因为没有泄漏内存,所以正在泄漏文件描述符。 Valgrind不会跟踪这些内容,因此不会显示泄漏它们。
如果长时间运行的进程创建了很多管道或打开了很多文件而忘记关闭它们,则可能会用完该进程的文件描述符。该限制是由系统管理员设置的,通常为1024或更多。之后,管道或打开的系统调用将返回-1,以表示errno ENFILE失败。