Variables in Memory

The computer has finite resources for "remembering" things. So, you can't just keep asking it to remember data without at some point also telling it that it's ok to forget the data. Otherwise, at some point it will be completely full of stuff you told it to remember, and it just won't be able to remember anything new, even if most of that data isn't even accessible through variables anymore (this is called a memory leak). The duration of time between remembering the data (allocating space for it in memory) and telling your computer that it can forget the data (freeing/deallocating the space) is called the lifetime of the memory.

Date Lifetime 

Three categories for the lifetime of memory in order to understand how variables are stored:

Static, Stack, and Heap

Stack, heap, or in static/global memory are stored in RAM (Random Access Memory).

They occupy different regions of RAM based on their storage duration and allocation mechanism.

Memory Layout Representation 
|-----------------------------------|  <- High Memory Address (ends at 0xFFFFFFFFFFFFFFFF)
|        Stack                      |  <--- Grows Downwards
|  (Local variables, function calls)|
|-----------------------------------|
|        Unused Space               |  <--- Space available for future allocation 
|-----------------------------------|
|        Heap                       |  <--- Grows Upwards
|  (Dynamically allocated memory)   |
|-----------------------------------|  <- Low Memory Address (starts at 0x0000000000000000 / null pointer) 
|        Text Segment               |  <--- Program instructions / Compiled Sourcecode / Machine Code in 0 & 1
|-----------------------------------|
|        Initialized Data           |  <--- Global and static variables (initialized)
|-----------------------------------|
|        Uninitialized Data (.bss)  |  <--- Global/static variables (uninitialized)
|-----------------------------------|

Directionality Matters: The upward growth of the heap and downward growth of the stack is crucial for efficient memory utilization, error detection, performance, and cache optimization.

Safety Mechanism: This design allows for better control over memory usage and helps prevent memory-related errors, making it an important aspect of system and application architecture.

Memory Addresses

Within RAM there is Memory addresses, which are fundamental to how data is accessed and manipulated in programming. They allow the CPU to locate and retrieve data stored in RAM, making them essential for efficient computation and memory management. 

In computer systems, a memory address is a unique identifier for a location in memory where data is stored. Whether a memory address is high or low does not affect speed, but rather designates location.  Memory addresses are typically represented in hexadecimal format. Here are a few examples:

#include <iostream>

int main() {
    int x = 42;  // Declare an integer variable
    std::cout << "Memory address of x: " << &x << std::endl;  // Print the memory address of x
    return 0;
}
Memory address of x: 0x7fffc3a1a4b8

In C++ coding, the Static, Heap, and Stack are corelated with their associated variables, which are stored through memory addresses. 

Variables in Memory

variable - refers to a named memory location that can hold data that might change during program execution.

int number;   // Declaring an `int` variable named `number`
int number = 42;   // Declaring and initializing `number` with 42.

When you declare a variable, the system allocates memory to store the value, and that memory is identified by the variable name. The compiler (GCC, Clang, etc) maps these names to actual memory addresses when the program is compiled and executed.

Depending on the context (stack, heap, or static), this memory may reside in different regions: 

1. Static Variables

Storage Duration:

Scope:

Memory Location:

Initialization:

When to Use:

Pros:

Cons:

#include <iostream>

static int globalStatic = 42; // Static global variable (file scope)

void function() {
    static int localStatic = 10; // Static local variable (function scope)
    localStatic++;
    std::cout << "Local Static: " << localStatic << std::endl;
}

int main() {
    function(); // Prints 11
    function(); // Prints 12
    return 0;
}


2. Heap (Free Store) Variables

Storage Duration:

Scope:

Memory Location:

Initialization:

When to Use:

Pros:

Cons:

#include <iostream>

int main() {
    int* heapVar = new int(5); // Dynamically allocated on the heap
    std::cout << "Heap Variable: " << *heapVar << std::endl;

    delete heapVar; // Must be manually deallocated to avoid memory leak
    return 0;
}

3. Stack Variables (Automatic Storage Duration)

Stack will pretty much never exhaust it unless 

Unique to stack is the stack frame, which is a structured block of memory on the stack that is created when a function is called.

 It holds:

Storage Duration:

Scope:

Memory Location:

Initialization:

When to Use:

Pros:

Cons:

#include <iostream>

void function() {
    int stackVar = 10;  // Allocated on the stack
    std::cout << "Stack Variable: " << stackVar << std::endl;
} // 'stackVar' is destroyed here when function exits

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



Revision #23
Created 24 September 2024 21:51:45 by victor
Updated 13 October 2024 21:47:18 by victor