2

I'm currently studying algorithms and advanced data structures; since I'm familiar with C and it does provide a great level of control above implementation and pointer usage I'm using it to test the understanding of the subject so far.

When testing structures that need dynamic things like lists and trees I asked myself: since C doesn't have a garbage collector, if I don't call the free() function in order to deallocate all the variables I dynamically allocate, where does that memory go?

Other related questions incude (sorry for misusing some terms, I don't have much experience in low level abstraction):

  • Does the compiler use the actual hard drive resources (like a variable is in the x record of my drive) or it "instantiates" a portion of virtual memory to compile and run my programs?

  • Do I have lots of lists, trees and graphs in my hard drive, all of them involving counts from 0 to 100 or the strings "abcd" and "qwerty"?

  • Does the OS recognize said data as garbage or I'm stuck with this junk forever until I format the drive?

I'm really curious about it, I never went below the C level of abstraction.

alemootasa
  • 83
  • 2
  • 9
  • The memory is not free, then it will be a zombie memory. Other processes can't use that memory in future. – Rajeshkumar Jun 16 '17 at 10:44
  • Its probably worth mentioning *why* C does not have a garbage collector - speed. Garbage collection is a huge overhead, although the algorithms have improved over the years. It is also worth mentioning that even garbage collection does not return freed (virtual) memory to the operating system, it makes it available for reuse (there is an exception on Windows with an empty page). Of course everything* is marked for reuse when the process completes. *Certain pages may be shared, so won't be freed. By the way, not sure why you are talking about a hard drive? – cdarke Jun 16 '17 at 11:07
  • 1
    There are cases where even garbage collecting languages can't help - like I/O descriptor leaks you can easily create in GC languages or distributed system resource leaks you manage to create in on another server. GCs are no universal remedy against careless programming. – tofro Jun 16 '17 at 12:36
  • @Rajeshkumar Other processes usually can't use garbage-collected memory either. Garbage collectors tend not to release memory back to the operating system. – user207421 Aug 23 '22 at 07:18

6 Answers6

7

since C doesn't have a garbage collector, if I don't call the free() function in order to deallocate all the variables I dynamically allocate, where does that memory go?

This is not (and cannot really be) defined by the C11 standard (read n1570).

However, let's pretend you run an executable produced by some C compiler on some familiar operating system (like Linux or Windows or MacOSX). Actually you are running some process which has some virtual address space.

The virtual memory and paging subsystem of the operating system kernel would put most useful pages - the resident set size - of that virtual address space in RAM and configure the MMU; read about demand paging & thrashing & page cache & page faults.

When that process terminates (either by nicely exiting or by some abnormal situation, like a segmentation fault) the operating system is releasing every resources used by your process (including the virtual address space of that process).

Read Operating Systems: Three Easy Pieces for much more.

However, if you don't have any operating system, or if your OS or processor don't support virtual memory (think of some Arduino board) things can be widely different. Read about undefined behavior and runtime systems.

On Linux, you can query the address space of a process of pid 1234 by using proc(5). Run in a terminal cat /proc/1234/maps or use pmap(1). From inside the process, read /proc/self/maps as a sequential file. See this.

You could also study the source code of open source standard libraries like GNU libc (above syscalls(2) on Linux) or of musl-libc, or use strace(1) to understand what system calls are done.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
3

C (and other non-garbage-collecting languages) has no concept of garbage at all, and thus no need to collect it somehow - Either you hold a valid pointer to some allocated memory, then it's considered "valuable memory", or you don't, then your program is just wrong - It's as simple as that.

The latter case is something C doesn't even evaluate any further - There's no point in researching what happens in a program "that's wrong" other than fixing it.

tofro
  • 5,640
  • 14
  • 31
2

Languages like C and C++ use dynamic heap allocation through dedicated functions/operators like malloc and new. This allocates memory on the heap, in RAM. If such a program fails to free the memory once done using it, then the programmer has managed to create a certain kind of bug called memory leak. Meaning that the program now consumes heap memory that cannot be used, since there is nothing in the program pointing at it any longer.

However, all memory allocated by a process is freed by the OS when the process is done executing. If the process failed to clean up its own heap allocations, the OS will do it. It is still good practice to manually clean up the memory though, but for other reasons (exposes latent bugs).

Therefore the only concern with memory leaks is that they cause programs to consume too much RAM while they execute. Once the process is done executing, all memory - including leaked memory - is freed.

There is no relation between the heap and your hard drive, just as there is no relation between the stack and your hard drive. The hard drive is used for storing the executable part of your program, nothing else. The heap, stack and other such memory areas are for storing data when your program is executing. Since they are allocated in RAM, all info in such areas is lost when the program is done executing.

The reason why some languages introduced garbage collection, was to remove the problem with memory leaks. A garbage collector is a background process of sorts, that goes through a program's heap memory and looks for segments of data which no part of the program is pointing at, then free those segments. Since the garbage collector does this, there is no need for free()/ delete.

This comes at the expense of execution speed, since the garbage collector needs to be executed now and then. This is one of many reasons why languages like Java and C# are slower than C and C++ by design. And it is also the reason why C and C++ don't have and never will have a garbage collector, since those languages prioritize execution speed.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • You can find garbage collection libraries for both C & C++; see [this](https://softwareengineering.stackexchange.com/a/350868/40065) – Basile Starynkevitch Jun 16 '17 at 12:00
  • 1
    @BasileStarynkevitch Yeah you can find all kinds of garbage libraries written for those languages... But garbage collection will never be included in the standard. – Lundin Jun 16 '17 at 12:06
  • 4
    @Lundin "garbage libraries", yes that's true as well, but unrelated ;) – tofro Jun 16 '17 at 12:11
  • I am not so sure about C++ & GC. Some parts of the standard are GC related.... e.g. [std::declare_reachable](http://en.cppreference.com/w/cpp/memory/gc/declare_reachable) and friends. – Basile Starynkevitch Jun 16 '17 at 12:13
  • 1
    Contents of memory may at some point get swapped out to the storage device if actual memory is insufficient to map all virtual memory requests, which is a common consequence of not freeing unused memory... But the swap area is eventually reclaimed when the faulty program finally exits or is killed, or the system is restarted after a crash. – chqrlie Feb 27 '21 at 09:22
0

If you don't free a resource, it stays allocated. The C compiler knows nothing about hard drives. You can read and write files with C and the appropriate IO libraries. So yes, your hard disk might be littered with stuff from running your software, but the C language or compiler isn't responsible to clean it up. You are. You can clean up your files manually, or code your C programs to clean up after themselves. Get a good book on C.

TomServo
  • 7,248
  • 5
  • 30
  • 47
-1

In languages like C which has no native garbage collection, any instantiated variables are held in volatile memory (RAM not HDD) until such times as either the application releases it or when the application closes. This can cause major issues on machines with limited memory as the memory allocation for the application continues to grow when objects are not 'disposed' throughout its lifecycle until there is no memory left and the application crashes and burns.

In answer to point 2 and 3 (objects on the HDD eg Trees, Graphs), no, they will not be littering your HDD as the objects are only created in memory (RAM) and only live while the application is running, closing the app will release the memory back (mostly) for use by other applications.

See this link for reference to hopefully help understand C Variables a little more.

-2

That memory you are talking about doesn't go anywhere.

It just remains there allocated and unable to be used by any other program until the program that allocated it completes its execution. Then, roughly, the operating system comes and "cleans" all the remains of that application from memory.

It is advised to free the memory yourself since the OS does that way slower than any application would do it (it has to cross-check with every other application running to make sure it doesn't free something it shouldn't be).

  • 3
    That last paragraph is completely wrong. Most, if not all, operating systems are far more efficient at freeing memory on exit than any application could ever be. There are situations where things it can be several orders of magnitude faster to let exit free memory instead of doing it yourself (malloc with inline boundary tags on a machine that's swapping for example). And I don't know where you got that "cross-check" bit from, but that is done with simple reference counting which is necessary regardless of you freeing the memory or not. – Art Jun 16 '17 at 10:57
  • 2
    I would prefer the term "process" to "program". The same program could be running in several different processes, when the process ends then the page table is destroyed and the reference count on pages in RAM will be decremented. – cdarke Jun 16 '17 at 11:02