Search code examples
carraysmemory-leaksgarbage-collectionc-strings

Does garbage collection happen when we initialize a char array with a string literal in c?


When we write the following line of code in C,

      char local_arr[] = "I am here";

the literal "I am here" gets stored in the read only part of the memory(say RM). How I visualize it is that it gets stored contiguously in the RM (Is that right?). Then the array local_arr (i.e local array) copies this array index by index from its location in RM.

But what happens to the literal after the local_array copies it? Is it lost thereby causing memory leaks? Or is there some sort of garbage collector like in Java that cleans up unreferenced objects?

For example if i write a piece of code as follows :

for(int i=0;i<100000;i++)
    char local[] = "I am wasting memory";

would I not run out of memory? Will each iteration create a new instance of identical literals with each iteration? Or will they all refer to the same literal since the value of the literal everytime is same?

Does RM belong to the heap memory or a specialized segment in heap?

Also the local array is stored in the stack, right? What if I use a dynamic array or global array. What happens then?


Solution

  • C does not have garbage collection, so if you forget to deallocate allocated memory with the proper deallocator, you get a memory leak.
    While sometimes a conservative garbage collector like the Boehm collector is used, that causes lots of extra headaches.

    Now, there are four types of memory in C:

    • static memory: This is valid from start to end. It comes in flavors logically read-only (writing is Undefined Behavior) and writeable.
    • thread-local memory: Similar to static memory, but distinct for each thread. This is new-fangled stuff, like all threading support.
    • automatic memory: Everything on the stack. It is automatically freed by leaving the block.
    • dynamic memory: What malloc, calloc, realloc and the like return on request. Do not forget to free resp. using another appropriate deallocator.

    Your example uses automatic memory for local_arr and leaves the implementation free to initialize it to the provided literal whichever way is most efficient.

    char local_arr[] = "I am here";
    

    That can mean, inter alia:

    • Using memcpy/strcpy and putting the literal into static memory.
    • Constructing the array on the stack by pushing the parts, thus putting it into the executed instructions.
    • Anything else deemed opportune.

    Also of interest, C constant literals have no identity, so can share space.
    Anyway, using the as-if rule, many times static (and even dynamic / automatic) variables can be optimized away.