#include <stdio.h>
#include <stdlib.h>
 
/**
 * @brief Analyse comparative de l'allocation Statique (Stack) et Dynamique (Heap).
 * Ce cours illustre comment la Pile gere l'adresse et le Tas gere la donnee.
 */
void pointerFunc() {
    
    /* 1. ALLOCATION STATIQUE (SUR LA PILE / STACK)
       L'identificateur 'ptr' est lui-meme une variable locale.
       Le systeme reserve immediatement un emplacement sur la PILE pour stocker 
       une adresse (8 octets sur architecture 64-bit).
       Etat : ptr est sur la Pile, mais sa valeur est 'indeterminee'.
    */
    int* ptr;
 
    /* 2. ALLOCATION DYNAMIQUE (LIAISON PILE-TAS)
       - malloc() : Reserve un bloc dans le TAS (Heap).
       - Affectation (=) : On ecrit l'adresse du bloc du TAS a l'interieur 
         de la variable 'ptr' qui reside sur la PILE.
       Concept : La Pile contient le "GPS" (l'adresse), le Tas contient le "Terrain".
    */
    ptr = (int*)malloc(sizeof(int));
 
    /* 3. DEREFERENCEMENT (INDERECTION DE LA PILE VERS LE TAS)
       L'operateur '*' commande au processeur de lire l'adresse sur la PILE,
       de "sauter" vers cette coordonnee dans le TAS, et d'y inscrire '25'.
       Action : On modifie le Tas via un identificateur situe sur la Pile.
    */
    *ptr = 25;
 
    /* 4. INSPECTION DE LA DUALITE MEMOIRE
       &ptr : L'adresse du pointeur lui-meme (ou il est sur la PILE).
       ptr  : L'adresse stockee (vers ou il pointe dans le TAS).
       *ptr : La valeur finale (ce qui est reellement dans le TAS).
    */
    printf("Emplacement du pointeur (sur la PILE) : %p\n", (void*)&ptr);
    printf("Destination pointee    (dans le TAS)  : %p\n", (void*)ptr);
    printf("Valeur finale          (dans le TAS)  : %d\n", *ptr);
 
    /* 5. DEALLOCATION DU TAS
       free(ptr) : Libere la memoire dans le TAS. 
       Note : Cette instruction ne modifie PAS la Pile. 
       'ptr' existe toujours sur la Pile et contient toujours l'adresse du Tas, 
       bien que celle-ci soit desormais invalide (Dangling Pointer).
    */
    free(ptr);
 
    /* 6. NEUTRALISATION SUR LA PILE
       ptr = NULL : On remplace l'adresse invalide par 0x0 sur la PILE.
       Le lien entre la Pile et le Tas est officiellement rompu.
    */
    ptr = NULL;
 
} /* FIN DE PORTEE : La variable 'ptr' est automatiquement depilee (Stack Pop). */
sequenceDiagram
    participant S as PILE (Stack)
    participant C as CPU (Code)
    participant T as TAS (Heap)

    Note over S,T: 1. Declaration
    C->>S: Reserve espace pour ptr
    S-->>C: ptr est indefini

    Note over S,T: 2. Allocation
    C->>T: malloc request
    T-->>C: Adresse 0x100
    C->>S: Ecrit 0x100 dans ptr

    Note over S,T: 3. DEREFERENCEMENT
    C->>S: Lit adresse dans ptr
    S-->>C: Renvoie 0x100
    C->>T: Ecrit 25 a l'adresse 0x100

    Note over S,T: 4. Liberation
    C->>T: Libere zone 0x100
    Note right of S: ptr contient encore 0x100

    Note over S,T: 5. Neutralisation
    C->>S: Met ptr a NULL (0x0)