POINTEURS, PILE, HEAP ET MÉMOIRE DYNAMIQUE

Salut ce forum apprends les bases du c++

Moderator: Rick

Post Reply
Hydraxx
Site Admin
Posts: 114
Joined: Mon Jan 12, 2026 4:04 pm
Location: France
Contact:

POINTEURS, PILE, HEAP ET MÉMOIRE DYNAMIQUE

Post by Hydraxx »

POINTEURS, PILE, HEAP ET MÉMOIRE DYNAMIQUE

À QUOI ÇA SERT ?

Le pointeur est l’une des notions centrales du C et du C++.

Un pointeur contient une adresse.

Cela permet :
  • d’accéder indirectement à une donnée ;
  • de partager un objet entre fonctions ;
  • de parcourir un buffer ;
  • de manipuler des structures ;
  • d’utiliser de la mémoire dynamique ;
  • d’interagir avec les API système ;
  • d’interagir avec du matériel ou des mappings.

1. ADRESSE D’UNE VARIABLE

Code: Select all

int value{42};
value possède une adresse mémoire.

Pour l’obtenir :

Code: Select all

&value
Exemple :

Code: Select all

int* ptr{&value};
ptr contient l’adresse de value.


2. DÉRÉFÉRENCEMENT

Code: Select all

*ptr
signifie :

"Accède à l’objet situé à l’adresse contenue dans ptr."

Exemple :

Code: Select all

int value{42};
int* ptr{&value};

*ptr = 100;
value vaut maintenant 100.


3. POURQUOI LE TYPE DU POINTEUR EST IMPORTANT

Code: Select all

int* ptr;
indique que l’adresse désigne un int.

Le compilateur sait donc :
  • combien d’octets lire ;
  • comment interpréter les bits ;
  • comment avancer avec ptr + 1.
Si sizeof(int) == 4 :

Code: Select all

ptr + 1
avance de 4 octets.


4. nullptr

Code: Select all

int* ptr{nullptr};
Cela signifie :

"Ce pointeur ne désigne actuellement aucun objet."

Avant d’utiliser un pointeur potentiellement nul :

Code: Select all

if (ptr != nullptr)
{
    std::cout << *ptr;
}
Ou :

Code: Select all

if (ptr)
{
}

5. POINTEUR NON INITIALISÉ


Très dangereux :

Code: Select all

int* ptr;
*ptr = 42;
ptr contient une valeur indéterminée.

Tu vas écrire à une adresse inconnue.

Toujours préférer :

Code: Select all

int* ptr{nullptr};

6. STACK


Exemple :

Code: Select all

void function()
{
    int x{42};
}
x a une durée de stockage automatique.

En pratique, sans optimisation, il sera souvent placé dans la stack frame.

Quand function() se termine, x cesse d’exister.

Attention :

Le standard C++ raisonne en termes de durée de stockage et de durée de vie. Le compilateur peut garder x dans un registre et ne jamais lui réserver réellement de case sur la pile.


7. HEAP / FREE STORE

Code: Select all

int* ptr = new int{42};
new :
1. obtient du stockage ;
2. construit un int dedans ;
3. retourne son adresse.

Libération :

Code: Select all

delete ptr;

8. POURQUOI delete ?


Si tu ne libères jamais :

Code: Select all

while (true)
{
    new int[1000];
}
la consommation mémoire augmente.

C’est une fuite mémoire.


9. TABLEAU DYNAMIQUE

Code: Select all

int* array = new int[100];
Libération correcte :

Code: Select all

delete[] array;
Ne pas faire :

Code: Select all

delete array;
car new[] doit correspondre à delete[].


10. DANGLING POINTER

Code: Select all

int* ptr = new int{42};

delete ptr;

std::cout << *ptr;
Après delete, l’objet n’existe plus.

Mais ptr contient encore l’ancienne adresse.

C’est un dangling pointer.

Le déréférencer est un comportement indéfini.


11. DOUBLE FREE

Code: Select all

delete ptr;
delete ptr;
La seconde libération tente de libérer une zone qui n’appartient plus à l’objet.

Comportement indéfini.


12. USE-AFTER-FREE

Code: Select all

delete ptr;

ptr->field = 1;
Tu utilises un objet après sa destruction.

C’est une classe de vulnérabilités très sérieuse.


13. ARITHMÉTIQUE DES POINTEURS

Code: Select all

int values[4]{10, 20, 30, 40};

int* ptr = values;
ptr pointe sur values[0].

Code: Select all

ptr + 1
pointe sur values[1].

Code: Select all

*(ptr + 2)
donne 30.

Donc :

Code: Select all

values[2]
est conceptuellement équivalent à :

Code: Select all

*(values + 2)

14. ONE-PAST-THE-END


Pour un tableau de N éléments, on peut former un pointeur juste après le dernier élément.

Il peut être utilisé comme borne.

Mais :

Code: Select all

*end
est interdit.

C’est exactement le principe de nombreux itérateurs C++.


15. POINTEUR VERS STRUCT

Code: Select all

struct Process
{
    int pid;
};

Process p{1234};
Process* ptr{&p};
Accès :

Code: Select all

ptr->pid
équivaut à :

Code: Select all

(*ptr).pid

16. POINTEUR ET ADRESSE VIRTUELLE


En user-mode moderne, une adresse contenue dans un pointeur est généralement une adresse virtuelle.

Exemple conceptuel :

Code: Select all

0x00007FF612341000
Ce n’est pas directement l’adresse d’une cellule de RAM physique.

Le processeur utilise :
  • MMU ;
  • tables de pages ;
  • TLB ;
pour traduire virtuel vers physique.

Donc :

pointeur C++ ≈ adresse virtuelle dans l’espace du processus.


17. malloc CONTRE new


malloc :

Code: Select all

void* mem = malloc(100);
alloue des octets bruts.

new :

Code: Select all

MyObject* obj = new MyObject();
alloue ET construit l’objet.

delete :
détruit l’objet puis libère.

free :
libère le bloc malloc.

Ne jamais mélanger :

Code: Select all

new -> free
malloc -> delete

18. POURQUOI LE C++ MODERNE ÉVITE new/delete MANUEL


Parce qu’ils sont faciles à mal gérer.

On préfère :

Code: Select all

std::vector
std::string
std::unique_ptr
Exemple :

Code: Select all

auto ptr = std::make_unique<MyObject>();
La mémoire est libérée automatiquement quand ptr meurt.


À RETENIR


Le pointeur est puissant parce qu’il donne un accès direct/indirect à la mémoire.

Mais il impose de maîtriser :
  • validité ;
  • taille ;
  • durée de vie ;
  • ownership ;
  • alignement ;
  • bornes.
Les bugs de pointeurs sont au cœur de nombreux crashs et vulnérabilités C/C++.

Return to “Bases du C++”

Who is online

Users browsing this forum: No registered users and 1 guest