What happens to statically allocated memory after its scope ends?

2.4k views Asked by At
void PrintArray()
{
  int a[4] = {4,3,1,5};
  for(int i=0; i<4; i++)
    cout<<a[i];
}

What Exactly happens to the memory allocated to the pointer variable 'a' and the 4-integer block pointed to by 'a' after this function's call is completed? Does the memory of the block and pointer variable get de-allocated or does it create some sort of memory leak?

5

There are 5 answers

0
John Bode On

the pointer variable 'a' and the 4-integer block pointed to by 'a'

First, we need to clear up a basic misconception here. a is not a separate pointer variable distinct from the 4-element array; a is the 4-element array. The address of a and the address of a[0] are the same thing. Under most circumstances, the expression a is converted from type "4-element array of int" to "pointer to int", and the value of the expression is the address of the first element in the array.

To answer the question, since a was declared within a block and without the static keyword, it has automatic storage duration, meaning that the memory occupied by the array is released when you leave the enclosing scope (in this case, the body of the function).

0
ouah On

In C, an automatic object like a is discarded at the exit of the block where it has been declared.

1
BrandonLWhite On

The memory does not leak. It is not allocated on the heap. Now, there is likely 2 different memory locations involved here.

  1. The location where the { 4,3,1,5 } initializer is stored. Typically initializers like this are stored in the data segment. In an embedded system this could be read-only flash. On a PC or whatever though, this is going to just be a RAM area that is initialized with your program image (eg. EXE) and isn't modified. After the function exits, it is still there. But it is not a leak -- just a part of your program's memory footprint (some might say static memory).
  2. The stack memory allocated for a[] in PrintArray() function scope. What the compiler does is allocate some stack space and then copies the values at the beginning of the function from the data segment. This is generally what takes place, so that if you modify any of the elements in a[], it only effects that array for that particular function call. When PrintArray() gets called again, the original initializer is unmodified and available for reuse. It would be weird/unexpected if subsequent calls to PrintArray() initialized to something besides { 4,3,1,5 } due to a previous invocation mutating the value. However, you aren't modifying it here, so it's plausible that optimizations may not allocated anything on the stack. YMMV. Assuming a[] does reside on the stack, it will be deallocated automatically (hence auto variable) upon function exit.

Of course, exactly what is taking place depends upon your compiler, linker, settings (especially optimizations), and target.

0
Sadbrute On

Automatic variables are not static, they are disposed of at the end of their scope (at the end of the function). A static variable will persist, it will keep it's value, even if it's called in a function. Here's a link about extern/static variables for further details.

0
Shafik Yaghmour On

a is not a static variable it is an automatic variable, from the draft C99 standard section 6.2.4 Storage durations of objects paragraph 4 says:

An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration.

In paragraphs 3 it describes the lifetime of static as the lifetime of the program and in paragraph 5 says:

For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. [...]

So in other words for an automatic variable it's lifetime extends to it's scope, in this case as scope is the function PrintArray and the storage associated with it is released after that scope is exited.

For C++ the relevant section from the draft standard is 3.7.3 Automatic storage duration paragraph 1 says:

Block-scope variables explicitly declared register or not explicitly declared static or extern have automatic storage duration. The storage for these entities lasts until the block in which they are created exits.