1

From what I read, fclose() is basically like the free() when memories been allocated but I also read that the operating system will close that file for you and flush away any streams that were open right after it terminates. I've even tested a few programs without fclose() and they all seem to work fine.

rubber boots
  • 14,924
  • 5
  • 33
  • 44
Cast
  • 61
  • 10
  • 1
    What if your program runs for many hours and wants to open and close many files? You also don't have to `free()` memory but if you don't, you'll eventually have used up all resources at some point. – 5gon12eder Nov 08 '15 at 21:24
  • If you're just about to exit anyway then the C runtime will take care of it for you and there's no benefit to doing it manually. Perhaps you might use it to flush the output in case you suspect that the clean-up may crash. In the longer-running case you may use it to free up resources, there's a finite number of file slots and keeping a file open often places a lock on it such that it may not be accessed freely from other applications until your own has exited. – doynax Nov 08 '15 at 21:29
  • I have seen more than one instance where the file descriptor is closed OK but pending write buffers are NOT flushed, resulting in files of length 0, – Martin James Nov 08 '15 at 21:45

2 Answers2

6

A long-running process (ex. a database or web browser) may need to open many files during its lifetime; keeping unused files open wastes resources, and potentially locks other processes out of using the files.

Additionally, fclose flushes the user-space buffer that is frequently used when writing to files to improve performance; if the process exits without flushing that buffer (with fflush/fclose), the data still in the buffer will be lost.

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
1

Most modern OSes will also reclaim the memory you malloc()'ed, but using free() when appropriate is still good practice. The point is that once you no longer need a resource you should relinquish it, so the system can repurpose whatever backing resources were reclaimed for use by other applications (typically, memory). Also there are limits on the number of file descriptors you can keep open at the same time.

Apart from that there are further considerations in the case of open() and friends, specifically by default open file descriptors are inherited accross thread and fork()'ed process boundaries. This means that if you fail to close() file descriptors, you may find that a child process can access files opened by the parent process. This is typically undesirable, it's a trivial security hole if you want a privileged parent process to spawn a slave process with lesser privileges.

Additionally, the semantics of unlink() and friends are that the file contents are only 'deleted' once the last open file descriptor to the file is close()'d so again: if you keep files open for longer than strictly necessary you cause suboptimal behaviour in the overall system.

Finally, in the case of sockets a close() also corresponds to disconnecting from the remote peer.

user268396
  • 11,576
  • 2
  • 31
  • 26
  • As far as I know, no OS reclaims malloc'd memory. As I understand it, the OS is usually not even aware of malloc/free as those happen purely inside the user-space of a process. Even with the corresponding kernel calls for page allocation/deallocation an OS kernel will only reclaim those pages of a process that said process specifically tells it to. It won't try to reclaim memory pages on its own. – Dreamer Nov 08 '15 at 22:11
  • @Dreamer: the OS is entirely aware of what pages of memory are currently claimed by which processes. If a process dies, AFAIK those pages are unmapped (if no other process uses the same ones also), effectively reclaiming the physical memory for future use. Of course there are plenty of OS'es out there in the realtime/embedded space which don't really do paging or virtual memory. – user268396 Nov 08 '15 at 22:50
  • @user268396 is correct. Any non-trivial OS will surely deallocate any pages that are no longer claimed by any process. The kernel does not know or care about sub-allocators like malloc, only it's own virtual memory manager state data. When a process terminates, the OS can, and will, stop all its threads and then release all memory pages and other resources that are not shared. If that did not happen, 'kill-9' and Task Manager 'End Process' would be ineffective at best. – Martin James Nov 09 '15 at 02:35
  • @user268396: yes, absolutely, the OS reclaims pages of terminated processes. And I did not claim otherwise. But the OS does only know which process owns which pages. It is not aware of which part of which pages is malloc'd - if any at all. And so an OS cannot reclaim pages from a process until either the process terminates or the process itself instructs the OS to reclaim said pages. That's why I consider your initial statement that the OS reclaims the memory you malloc'd to be incorrect. – Dreamer Nov 09 '15 at 22:07