Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does "Memory allocated at compile time" really mean?

In programming languages like C and C++, people often refer to static and dynamic memory allocation. I understand the concept but the phrase "All memory was allocated (reserved) during compile time" always confuses me.

Compilation, as I understand it, converts high level C/C++ code to machine language and outputs an executable file. How is memory "allocated" in a compiled file ? Isn't memory always allocated in the RAM with all the virtual memory management stuff ?

Isn't memory allocation by definition a runtime concept ?

If I make a 1KB statically allocated variable in my C/C++ code, will that increase the size of the executable by the same amount ?

This is one of the pages where the phrase is used under the heading "Static allocation".

Back To Basics: Memory allocation, a walk down the history

like image 366
Talha Sayed Avatar asked Jan 25 '14 12:01

Talha Sayed


People also ask

What is compile time memory allocation?

When a variable is declared compiler automatically allocates memory for it. This is known as compile time memory allocation or static memory allocation. Memory can be allocated for data variables after the program begins execution. This mechanism is known as runtime memory allocation or dynamic memory allocation.

What happens when memory is allocated?

Memory allocation is a process by which computer programs and services are assigned with physical or virtual memory space. Memory allocation is the process of reserving a partial or complete portion of computer memory for the execution of programs and processes.

What is the meaning of compile time?

In computer science, compile time (or compile-time) describes the time window during which a computer program is compiled. The term is used as an adjective to describe concepts related to the context of program compilation, as opposed to concepts related to the context of program execution (runtime).

Is memory allocated at compile time in Java?

Compile time no memory allocation happens. Only at load and runtime.


1 Answers

Memory allocated at compile-time means the compiler resolves at compile-time where certain things will be allocated inside the process memory map.

For example, consider a global array:

int array[100]; 

The compiler knows at compile-time the size of the array and the size of an int, so it knows the entire size of the array at compile-time. Also a global variable has static storage duration by default: it is allocated in the static memory area of the process memory space (.data/.bss section). Given that information, the compiler decides during compilation in what address of that static memory area the array will be.

Of course that memory addresses are virtual addresses. The program assumes that it has its own entire memory space (From 0x00000000 to 0xFFFFFFFF for example). That's why the compiler could do assumptions like "Okay, the array will be at address 0x00A33211". At runtime that addresses are translated to real/hardware addresses by the MMU and OS.

Value initialized static storage things are a bit different. For example:

int array[] = { 1 , 2 , 3 , 4 }; 

In our first example, the compiler only decided where the array will be allocated, storing that information in the executable.
In the case of value-initialized things, the compiler also injects the initial value of the array into the executable, and adds code which tells the program loader that after the array allocation at program start, the array should be filled with these values.

Here are two examples of the assembly generated by the compiler (GCC4.8.1 with x86 target):

C++ code:

int a[4]; int b[] = { 1 , 2 , 3 , 4 };  int main() {} 

Output assembly:

a:     .zero   16 b:     .long   1     .long   2     .long   3     .long   4 main:     pushq   %rbp     movq    %rsp, %rbp     movl    $0, %eax     popq    %rbp     ret 

As you can see, the values are directly injected into the assembly. In the array a, the compiler generates a zero initialization of 16 bytes, because the Standard says that static stored things should be initialized to zero by default:

8.5.9 (Initializers) [Note]:
Every object of static storage duration is zero-initialized at program startup before any other initial- ization takes place. In some cases, additional initialization is done later.

I always suggest people to disassembly their code to see what the compiler really does with the C++ code. This applies from storage classes/duration (like this question) to advanced compiler optimizations. You could instruct your compiler to generate the assembly, but there are wonderful tools to do this on the Internet in a friendly manner. My favourite is GCC Explorer.

like image 197
Manu343726 Avatar answered Oct 02 '22 19:10

Manu343726