Adloun

informatique (MP2I/MPI) · Chapitre 8 · Application directe du cours

Où vit chaque variable

Mémoire, fichiers et entrées-sorties · niveau 2

Énoncé

Pour chacune des six entités de ce programme, dire dans quelle zone elle réside et quelle est sa durée de vie.


int globale = 1;

void ou_suis_je(int parametre) {
    int locale = 3;
    int* du_tas = malloc(sizeof(int));
    /* ... */
    free(du_tas);
}

Corrigé

EntitéZoneDurée de vieAdresse mesurée
ou_suis_jecodetout le programme0x102f53dd4
globaleglobalestout le programme0x102f58000
du_tas (le bloc pointé)tasdu malloc au free0x10365dbd0
parametrepilel'appel0x16ceae5fc
localepilel'appel0x16ceae5f8
du_tas (la variable)pilel'appel—

Les adresses de la dernière colonne ont été mesurées par un printf("%p", ...) sur chacune. Trois choses s'y lisent, et aucune n'est un détail :

  • Le code, les globales et le tas sont dans la même famille d'adresses (0x1...), tandis que la pile est très loin (0x16c...). Les deux zones croissent l'une vers l'autre, comme le montre la figure du début de ce chapitre — c'est ce qui leur laisse le maximum de place.
  • locale est à ...5f8 et parametre à ...5fc : quatre octets d'écart, et la locale est plus bas. La pile descend.
  • La distinction décisive porte sur du_tas : la variable est sur la pile et meurt au retour ; le bloc qu'elle désigne est sur le tas et survit tant qu'on ne l'a pas libéré. C'est exactement pourquoi on peut rendre un pointeur du tas et jamais un pointeur de pile.

Ces adresses changent à chaque exécution : le système décale les zones au hasard (ASLR) pour compliquer les attaques. Ce qui ne change pas, ce sont les écarts relatifs et l'appartenance aux zones.

Exercices semblables

Le cours du chapitre · Tous les exercices du chapitre