A Deep Dive into C Language Memory: Stack, Heap, Global, Constant, and Code Areas – Do You Really Understand Their Secrets?

Source: Chip Home

1. Memory Partitioning in C Language

The memory partitioning diagram of the C language is as follows:

A Deep Dive into C Language Memory: Stack, Heap, Global, Constant, and Code Areas - Do You Really Understand Their Secrets?Actually, one image is enough

1. Stack Area

Introduction to Stack Area

  • The stack area is automatically allocated and released by the compiler, managed automatically by the operating system, without manual management.

  • The contents in the stack area only exist within the function scope, and when the function execution ends, these contents will also beautomatically destroyed.

  • The stack area grows in the direction of memory addresses from high to low, its maximum size is determined at compile time, it is fast but has poor flexibility, and the maximum space is not large.

  • The stack area follows the Last In First Out (LIFO) principle, meaning the first one in is the last one out, and the last one in is the first one out when released.

Stored Contents

  • Temporarily created local variables and const defined local variables are stored in the stack area.

  • During function calls and returns, its entry parameters and return values are stored in the stack area.

2. Heap Area

Introduction to Heap Area

  • The heap area is allocated and released by the programmer.

  • The heap area grows in the direction of memory addresses from low to high, its size is determined by the system memory/virtual memory limit, it is slower but has greater flexibility and available space.

Function Call

  • Use malloc and other functions to implement dynamic memory allocation.

void *malloc(size_t);
  • The parameter size_t is the size of the allocated bytes. The return value is a void* type pointer that points to the starting address of the allocated space.(A void* type pointer can be converted to any other type of pointer)

  • Use free function to release memory, otherwise it will cause memory leaks.

void free(void * /*ptr*/);
  • The parameter is the starting address of the allocated memory.

3. Global (Static) Area

Introduction to Global (Static) Area

  • Usually used for variables whose storage size can be determined at compile time, but it is used for global variables and static variables that are visible throughout the entire program execution.

  • The global area consists of .bss section and .data section which are readable and writable.

.bss Section

  • Uninitialized global variables and uninitialized static variables are stored in the .bss section.

  • Global variables initialized to 0 and static variables initialized to 0 are stored in the .bss section.

  • .bss section does not occupy executable file space, its content is initialized by the operating system.

.data Section

  • Initialized global variables are stored in the .data section.

  • Initialized static variables are stored in the .data section.

  • .data section occupies executable file space, its content is initialized by the program.

4. Constant Area

  • Strings and numbers and other constants are stored in the constant area.

  • Global variables modified by const are stored in the constant area.

  • During program execution, the content of the constant area cannot be modified.

5. Code Area

  • The program execution code is stored in the code area, and its value cannot be modified (if modified, an error will occur).

  • String constants and constants defined by define may also be stored in the code area.

II. STM32 Memory Allocation

1. Random Access Memory – RAM

  • RAM is the internal memory that exchanges data directly with the CPU, also called main memory (memory).

  • It can be read and written at any time, and it is very fast, usually serving as a temporary data storage medium for the operating system or other running programs.

  • When the power is turned off, RAM cannot retain data ( data disappears on power loss), if data needs to be preserved, it must be written to a long-term storage device (such as a hard disk).

2. Read-Only Memory – ROM

  • The data stored in ROM is generally pre-written before the machine is assembled, and can only be read during the operation of the machine, unlike random access memory which can be quickly and conveniently rewritten.

  • Data stored in ROM is stable and will not change after power loss.

This article uses the STM32F103 chip, and the default memory configuration in the Keil V5 environment is shown in the figure below:

A Deep Dive into C Language Memory: Stack, Heap, Global, Constant, and Code Areas - Do You Really Understand Their Secrets?

  • The ROM area starts at 0x8000000, with a size of 0x10000, this area is read-only, cannot be modified, and stores the code area and constant area.

  • The RAM area starts at 0x20000000, with a size of 0x5000, this area is readable and writable, storing the global (static) area, heap area and stack area.

The internal partitioning of this chip is shown in the figure below:

A Deep Dive into C Language Memory: Stack, Heap, Global, Constant, and Code Areas - Do You Really Understand Their Secrets?

III. Code Verification Based on STM32

1. Detailed Code as Follows

#include "main.h"
#include <string.h> // For string processing
#include <stdio.h> // For printf printing
#include <stdlib.h> // For heap allocation - calling malloc and free

#include "delay.h"
#include "uart3.h"
#include "led.h"

// Global Area
int q1; // Uninitialized global variable
static int q2; // Uninitialized static variable
const int q3; // Uninitialized read-only variable

int m1 = 1; // Initialized global variable
static int m2 = 2; // Initialized static variable

// Constant Area
const int m3 = 3; // Initialized read-only variable

int main(void)
{
    SystemCoreClockUpdate(); // Set system clock to 72M
    LED_GPIO_Config();
    Uart3_init();

    while (1)
    {
        // Stack Area
        int mq1; // Uninitialized local variable
        int *mq2; // Uninitialized local pointer variable

        int mq3 = 3; // Initialized local variable
        char qq[10] = "hello"; // Initialized local array

        const int mq4; // Uninitialized local read-only variable
        const int mq5 = 3; // Initialized local read-only variable

        // Heap Area
        int *p1 = malloc(4); // Initialized local pointer variable p1
        int *p2 = malloc(4); // Initialized local pointer variable p2

        // Global Area
        static int mp1; // Uninitialized local static variable
        static int mp2 = 2; // Initialized local static variable

        // Constant Area
        char *vv = "I LOVE YOU"; // Initialized local pointer variable
        char *mq = "5201314";

        printf("\nStack Area - Variable Addresses\n");
        printf("Uninitialized local variable :0x%p\r\n", &mq1);
        printf("Uninitialized local pointer variable :0x%p\r\n", &mq2);
        printf("Initialized local variable :0x%p\r\n", &mq3);
        printf("Initialized local array :0x%p\r\n", qq);

        printf("Uninitialized local read-only variable :0x%p\r\n", &mq4);
        printf("Initialized local read-only variable :0x%p\r\n", &mq5);

        printf("\nHeap Area - Dynamic Allocation Addresses\r\n");
        printf("Initialized local int pointer variable p1 :0x%p\r\n", p1);
        printf("Initialized local int pointer variable p2 :0x%p\r\n", p2);

        printf("\nGlobal Area - Variable Addresses\n");
        printf("Uninitialized global variable :0x%p\r\n", &q1);
        printf("Uninitialized static variable :0x%p\r\n", &q2);
        printf("Uninitialized read-only variable :0x%p\r\n", &q3);

        printf("Initialized global variable :0x%p\r\n", &m1);
        printf("Initialized static variable :0x%p\r\n", &m2);

        printf("Uninitialized local static variable :0x%p\r\n", &mp1);
        printf("Initialized local static variable :0x%p\r\n", &mp2);

        printf("\nConstant Area Addresses\n");
        printf("Initialized read-only variable :0x%p\r\n", &m3);
        printf("Initialized local pointer variable :0x%p\r\n", vv);
        printf("Initialized local pointer variable :0x%p\r\n", mq);

        printf("\nCode Area Addresses\n");
        printf("Program code area main function entry address :0x%p\n", main);

        led485_flicker();
        delay_ms(1000);

        free(p1);
        free(p2);
    }
}

Reprint Statement: All reprinted articles must indicate the original source or reprint source (if the reprint does not indicate the original source), if there is any infringement, please contact for deletion.

Leave a Comment