Skip to content

📌 1. DĂ©finitions & Cadre d'Ă©tude

En langage C, la mĂ©moire vive est modĂ©lisĂ©e comme un tableau linĂ©aire gĂ©ant d’octets adressables. Chaque emplacement mĂ©moire possĂšde une adresse unique, qui est un entier non signĂ© reprĂ©sentant sa position.

La mémoire allouée à un programme en exécution est traditionnellement découpée en plusieurs zones distinctes :

  1. La zone Texte (Code) : Contient le code machine exécutable du programme.
  2. La zone des données globales et statiques : Contient les variables globales et les variables locales dotées du qualificatif static.
  3. La pile (Stack) : Zone gérée automatiquement par le systÚme (LIFO : Last In, First Out). Elle stocke les variables locales des fonctions et les cadres de pile (stack frames) lors des appels de fonctions.
  4. Le tas (Heap) : Zone de mĂ©moire dite “dynamique”, gĂ©rĂ©e explicitement par le programmeur via des fonctions d’allocation et de libĂ©ration.

Un pointeur est une variable dont la valeur est l’adresse mĂ©moire d’une autre variable.

  • DĂ©claration : type *nom_variable; (ex: int *p;).
  • L’opĂ©rateur d’adressage & permet d’obtenir l’adresse d’une variable : p = &x;.
  • L’opĂ©rateur de dĂ©rĂ©fĂ©rencement * permet d’accĂ©der ou de modifier la valeur stockĂ©e Ă  l’adresse pointĂ©e : *p = 5;.

📐 2. ThĂ©orĂšmes fondamentaux & DĂ©monstrations clĂ©s

Section titled “📐 2. ThĂ©orĂšmes fondamentaux & DĂ©monstrations clĂ©s”

ThĂ©orĂšme d’équivalence entre tableaux et pointeurs

Section titled “ThĂ©orĂšme d’équivalence entre tableaux et pointeurs”

En C, le nom d’un tableau non qualifiĂ© est converti (decay) lors de son utilisation en un pointeur constant vers son premier Ă©lĂ©ment.

Soit T un tableau de type type et d’indice ii. L’accĂšs par notation tableau T[i] est syntaxiquement et sĂ©mantiquement rigoureusement Ă©quivalent Ă  l’arithmĂ©tique des pointeurs : T[i]≡∗(T+i)\text{T}[i] \equiv *(T + i)

L’adresse de l’élĂ©ment d’indice ii est calculĂ©e par le compilateur en tenant compte de la taille en octets du type sous-jacent sizeof(type)\text{sizeof}(\text{type}). Si AA est l’adresse de base du tableau TT (soit TT), l’adresse de T[i]T[i] est : Adresse(T[i])=A+i×sizeof(type)\text{Adresse}(T[i]) = A + i \times \text{sizeof}(\text{type}) Le dĂ©rĂ©fĂ©rencement de cette adresse par l’opĂ©rateur * donne directement la valeur stockĂ©e Ă  cet emplacement, prouvant l’identitĂ©.


Allocation dynamique sur le tas (malloc, calloc, realloc, free)

Section titled “Allocation dynamique sur le tas (malloc, calloc, realloc, free)”

L’utilisation du tas est indispensable lorsque la taille des donnĂ©es n’est pas connue Ă  la compilation ou doit persister au-delĂ  de la portĂ©e d’une fonction.

int *ptr = malloc(n * sizeof(int));
if (ptr == NULL) {
// Gestion de l'erreur d'allocation (memoire saturee)
exit(EXIT_FAILURE);
}

2. Allocation et initialisation à zéro avec calloc

Section titled “2. Allocation et initialisation Ă  zĂ©ro avec calloc”
int *ptr = calloc(n, sizeof(int)); // Met tous les octets a 0

Toute zone allouĂ©e dynamiquement doit ĂȘtre libĂ©rĂ©e exactement une fois pour Ă©viter les fuites de mĂ©moire (memory leaks) :

free(ptr);
ptr = NULL; // Bonne pratique pour eviter les "pointeurs pendouillants"

  1. Le pointeur pendouillant (dangling pointer) : AccĂ©der Ă  une zone mĂ©moire aprĂšs sa libĂ©ration par free, ou retourner l’adresse d’une variable locale (allouĂ©e sur la pile) d’une fonction qui s’est terminĂ©e.

    int* f() {
    int x = 5;
    return &x; // ERREUR GRAVE : x est detruit a la sortie de la fonction
    }
  2. La fuite mémoire (memory leak) : Oublier de libérer un bloc mémoire alloué par malloc/calloc, ou perdre le dernier pointeur y menant en écrasant sa valeur.

  3. Le dĂ©passement de tampon (buffer overflow) : Écrire ou lire en dehors des limites d’un tableau allouĂ© (notamment par erreur sur les indices 00 Ă  n−1n-1). En MP2I, ce type d’erreur entraĂźne un comportement indĂ©fini (undefined behavior) et peut corrompre la pile d’exĂ©cution.

  4. Confusion entre taille logique et taille physique (sizeof) : L’opĂ©rateur sizeof appliquĂ© Ă  un pointeur passĂ© en paramĂštre d’une fonction renvoie la taille du pointeur en mĂ©moire (ex: 88 octets sur une architecture 6464 bits), et en aucun cas la taille du tableau pointĂ©.