Danny Dyla
Danny Dyla

Reputation: 691

When is memory deallocated in c?

I am trying to find out when memory used for variables in c is freed. As an example, when would the integer i be freed in the following code snippet?

int function()
{
  int i = 1;
  // do some things
  return 0;
}

Upvotes: 5

Views: 4791

Answers (5)

Jim Balter
Jim Balter

Reputation: 16406

In C, as in all other languages, lexically scoped variables, such as i here, are only valid within their scopes -- the scope of i is from its declaration through the closing brace of the function. When exactly they are freed is often not specified, but in practical C implementations local variables are allocated on the call stack and their memory is reused once the function returns.

Consider something like

int function()
{
    int i; // beginning of i's scope
    {
        int j; // beginning of j's scope
        ...
    } // end of j's scope
    {
        int k; // beginning of k's scope
        ...
    } // end of k's scope

    return 0; // all locals of the function are deallocated by the time it is exited
} // end of i's scope

Scope determines when the variables can be accessed by name and, for local (auto) variables, when their content can be validly accessed (e.g., if you set a pointer to the address of a local variable, dereferencing the pointer outside the variable's scope is undefined behavior). Deallocation is a somewhat different matter ... most implementations won't do anything at the end of j or k's scope to "deallocate" them, although they will likely reuse the same memory for both variables. When function returns, most implementations will "pop" all locals off the stack, along with the return address, by a single decrement of the stack pointer, in effect "deallocating" their memory ... although the memory is still right there on the stack, ready to be "allocated" to the next function that is called.

Note that the terminology of your question is somewhat confused ... variables have scope, but it's memory, not variables, that is allocated and deallocated. Some variables may not even have any memory allocated for them if, for instance, they are constants or are never used in the program. And only the memory for local variables is allocated or freed as described above ... the memory for static and file scope variables is never freed, and only allocated when the program is loaded. And there is other memory -- heap memory -- that is explicitly allocated and freed by your program (via calls to malloc/realloc/calloc/strdup/free etc.). But although heap memory can be referenced by pointer variables, the memory for the pointer variables themselves consists just of the reference (memory address), with the variables having either local or static/file scope.

Upvotes: 12

Ahmed Masud
Ahmed Masud

Reputation: 22372

Automatic variables are local to a scope in C:

A scope is basically marked by '{' '}' so when you are inside a {} pair you are inside a scope. Of course scopes can be nested.

This is why in older C standard the local variables had to be defined at the top of a scope because it made writing the C compiler easier (the compiler would see a '{' and then all the variables and then statements) so it knew the variables it had to deal with. This changed in C99 (I think?) and later on where you can define variables anywhere in between statements.

This can be quite helpful of course:

int foo() 
{
     int k = 0; /* inside the scope of foo() function */

     for(; k < 10; k++) { /* don't need k = 0; here we set it to zero earlier */
         int i = 1; /* initialize inside the scope of the for loop */
         i = i * 2; /* do something with it */
         printf ("k = %d, i = %d\n", k, i);
     }

#if 0 
     printf ("i = %d\n", i); /* would  cause an unknown identifier error
                              * because i would be out of scope, if you changed
                              * #if 0 to #if 1 
                              */
#endif
    return 0;
}

int main() 
{
     foo();
     foo();
     return 0; 
}

Notice that i = 2 all the time for the iterations of the loop in foo()

A more fun thing to see is how the keyword static modifies the persistence of the variable.

int bar() 
{
     int k = 0; /* inside the scope of bar() function */

     for(; k < 10; k++) { /* don't need k = 0; here we set it to zero earlier */
         static int i = 1; /* initialize inside the scope of the for loop */
         i = i * 2; /* do something with it */
         printf ("k = %d, i = %d\n", k, i);
     }

#if 0 
     printf ("i = %d\n", i); /* would  cause an unknown identifier error
                              * because i would be out of scope, if you changed
                              * #if 0 to #if 1 
                              */
#endif
    return 0;
}

int main() 
{
     foo();
     foo();
     return 0; 
}

Note the changes and note how a static variable is treated.

What would happen to the for loop if you put the keyword static in front of int k = 0; ?

Interesting uses

C macros are very useful. Sometimes you want to define a complicated local macro rather than a function for speed and overall simplicity. In a project I wanted to manipulate large bit maps, but using functions to perform 'and' 'or' 'xor' operations was a bit of a pain. The size of bitmaps was fixed so I created some macros:

#define  BMPOR(m1, m2) do {                                  \
                 int j;                                      \
                 for (j = 0; j < sizeof(bitmap_t); j++ )     \
                     ((char *)(m1))[j] |= ((char *)(m2))[j]; \
         } while (0)

the do { } while(0) is a fun trick to let a scoped block be attached to if/for/while etc. without an issue, the block executes exactly once (since the while is checked at the END of the block), and when compiler sees while(0) it just removes the loop; and of course this lets you put a semi-colon at the end so IDEs and you (later) don't get confused about what it is.

The macro above was used as under:

int foo() 
{
      bitmap_t map_a = some_map(), map_b = some_other_map();
      BITOR(map_a, map_b); /* or map_a and map_b and put the results in map_a */
}

here the do {} while(0) allowed a local scope with a local variable j, a for loop and anything else that I might have needed.

Upvotes: 1

Rohan
Rohan

Reputation: 3078

Variable gets deallocated when the variable gets out of scope.In your code variable i will get deallocated after return 0 statement is executed. You can find more on variable scope here

Upvotes: 0

JeffRSon
JeffRSon

Reputation: 11186

i is allocated on the stack. It is freed when return is executed.

Upvotes: 1

David Schwartz
David Schwartz

Reputation: 182769

It will be freed when it goes out of scope. Since it has function scope, this will happen when the function returns.

Upvotes: 7

Related Questions