Cours sur la gestion de la mémoire

Développement système natif en c/c++ avec win32 ...

Moderator: Rick

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

Cours sur la gestion de la mémoire

Post by Hydraxx »

## La mémoire sous Windows

On continue avec un gros morceau : la mémoire.

Si tu comprends la mémoire sous Windows, tu comprends :

* pourquoi ça crash (0xC0000005)
* pourquoi ça leak
* pourquoi ça devient instable au bout de 2h
* pourquoi un bug “aléatoire” est en fait logique

Je vais te donner la vision claire + les fonctions Win32 indispensables (VirtualAlloc, HeapAlloc, mapping, protections, etc.). 8-)

---

### 1) Mémoire virtuelle vs mémoire physique

Sous Windows, ton programme voit une mémoire “virtuelle”.
Chaque processus a son propre espace d’adressage virtuel.
Deux processus peuvent utiliser la même adresse virtuelle sans partager la même RAM.

Le CPU (MMU) + Windows traduisent :
adresse virtuelle -> page physique (ou page du pagefile).

En user-mode, tu ne touches jamais la RAM physique directement.

---

### 2) Organisation générale d’un processus

Dans un processus tu as en gros :

* le code (.text)
* les données globales (.data / .bss)
* le heap (allocations dynamiques)
* les stacks (1 par thread)
* la mémoire mappée (DLL, fichiers, shared memory)

Important :

* chaque thread a son stack
* le heap est partagé entre threads du même processus

---

### 3) Stack vs Heap (différences utiles)

Stack :

* local au thread
* rapide
* taille limitée
* géré automatiquement (variables locales, appels de fonctions)

Heap :

* partagé dans le processus
* plus flexible
* plus lent
* c’est là que tu fais malloc/new (ou HeapAlloc)

Le heap est une source énorme de bugs :

* double free
* use-after-free
* buffer overflow
* race condition si plusieurs threads manipulent la même structure sans lock

---

### 4) Les heaps Windows (GetProcessHeap / HeapAlloc)

Windows a des heaps “Win32” gérés par le système.
Le plus courant : le heap du processus.

Fonctions indispensables :

* GetProcessHeap
* HeapAlloc
* HeapReAlloc
* HeapFree

Exemple minimal :

Code: Select all

#include <Windows.h>
#include <iostream>

int main()
{
HANDLE hHeap = GetProcessHeap();

```
int* p = (int*)HeapAlloc(hHeap, 0, sizeof(int));
if (!p) return 1;

*p = 123;
std::cout << *p << std::endl;

HeapFree(hHeap, 0, p);
return 0;
```

}
HeapReAlloc :

Code: Select all

p = (int*)HeapReAlloc(hHeap, 0, p, 10 * sizeof(int));
Très important :

* HeapFree libère le bloc, et après tu ne touches plus au pointeur.
* Si tu fais du multithread, protège les structures partagées (sinon tu auras des corruptions).

---

### 5) Créer son propre heap (HeapCreate / HeapDestroy)

Tu peux créer un heap dédié.
Utile si :

* tu veux isoler des allocations
* tu veux pouvoir tout libérer d’un coup
* tu veux limiter l’impact d’une corruption

Fonctions :

* HeapCreate
* HeapDestroy

Exemple :

Code: Select all

HANDLE hHeap = HeapCreate(0, 0, 0);
if (!hHeap) return 1;

void* p = HeapAlloc(hHeap, 0, 256);

// ...

HeapFree(hHeap, 0, p);
HeapDestroy(hHeap);
Note :

* HeapDestroy détruit le heap (et donc libère tout ce qui reste dedans).
* Pratique pour éviter les leaks si tu structures bien ton code.

Fonctions utiles autour du heap :

* GetProcessHeaps (liste des heaps du process)
* HeapSize (taille d’un bloc)
* HeapValidate (détecter corruption, utile en debug)
* HeapCompact (tente de compacter)
* HeapWalk (parcourir, plutôt debug/outils)
* HeapSetInformation (config, certaines options de sécurité selon version)

---

### 6) Allocations bas niveau par pages (VirtualAlloc / VirtualFree)

Le heap travaille en “blocs”.
VirtualAlloc travaille en “pages mémoire”.

C’est la base du bas niveau Windows.

Fonctions indispensables :

* VirtualAlloc
* VirtualFree
* VirtualProtect
* VirtualQuery

Exemple :

Code: Select all

LPVOID mem = VirtualAlloc(
NULL,
4096,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE
);

if (!mem) return 1;

// utilisation...

VirtualFree(mem, 0, MEM_RELEASE);
VirtualProtect (changer les droits) :

Code: Select all

DWORD oldProt;
VirtualProtect(mem, 4096, PAGE_READONLY, &oldProt);
VirtualQuery (inspecter une adresse : region, protections, état) :

Code: Select all

MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(mem, &mbi, sizeof(mbi));
---

### 7) Protections mémoire (et pourquoi ça crash)

Chaque page a des droits :

* lecture
* écriture
* exécution

Exemples :

* PAGE_READONLY
* PAGE_READWRITE
* PAGE_EXECUTE_READ
* PAGE_EXECUTE_READWRITE (à éviter en général)
* PAGE_NOACCESS

Le crash classique 0xC0000005 arrive quand :

* tu lis/écris à une adresse invalide
* tu écris dans une page non writable
* tu exécutes une page non executable
* tu utilises un pointeur NULL ou corrompu

C’est la base de 90% des crashs en C/C++.

---

### 8) Mémoire mappée (fichier ou shared memory)

Mapper un fichier en mémoire :

* très performant
* utile pour gros fichiers
* utile pour IPC (mémoire partagée)

Fonctions indispensables :

* CreateFileMapping
* OpenFileMapping
* MapViewOfFile
* UnmapViewOfFile
* FlushViewOfFile (si tu veux flush)
* CloseHandle

Exemple (schéma) :

Code: Select all

HANDLE hMap = CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE,
0, 0,
NULL
);

LPVOID view = MapViewOfFile(
hMap,
FILE_MAP_ALL_ACCESS,
0, 0, 0
);

// utilisation via pointeur...

UnmapViewOfFile(view);
CloseHandle(hMap);
---

### 9) Infos système utiles (taille de page, etc.)

Pour du bas niveau mémoire, tu dois connaître :

* taille de page
* allocation granularity

Fonctions indispensables :

* GetSystemInfo (ou GetNativeSystemInfo)
* GlobalMemoryStatusEx (infos RAM/commit, etc.)

Exemple :

Code: Select all

SYSTEM_INFO si;
GetSystemInfo(&si);
// si.dwPageSize, si.dwAllocationGranularity, etc.
---

### 10) Fonctions “legacy” (à connaître mais éviter)

Tu verras parfois :

* GlobalAlloc / GlobalFree
* LocalAlloc / LocalFree

C’est ancien et pas recommandé pour du code moderne.
Tu les rencontres dans du vieux code Win32, mais en 2026 tu fais plutôt :

* HeapAlloc
* VirtualAlloc
* new/malloc selon ton architecture

---

### 11) Règles simples (qui évitent 80% des bugs)

* Chaque allocation doit avoir sa libération (même chemin d’erreur).
* Ne mélange pas les familles :

* new/delete ensemble
* malloc/free ensemble
* HeapAlloc/HeapFree ensemble
* VirtualAlloc/VirtualFree ensemble
* Après un free, le pointeur est mort (mets le à NULL si besoin).
* Évite les gros tableaux sur le stack.
* En multithread, protège les structures partagées.
* Vérifie toujours les retours (NULL, GetLastError si nécessaire).

---

### 12) Liste “à connaître absolument” (résumé fonctions)

Heap (blocs) :

* GetProcessHeap
* HeapAlloc / HeapReAlloc / HeapFree
* HeapCreate / HeapDestroy
* HeapValidate / HeapSize
* GetProcessHeaps

Mémoire pages (bas niveau) :

* VirtualAlloc / VirtualFree
* VirtualProtect
* VirtualQuery

Mapping :

* CreateFileMapping / OpenFileMapping
* MapViewOfFile / UnmapViewOfFile
* FlushViewOfFile

Infos :

* GetSystemInfo / GetNativeSystemInfo
* GlobalMemoryStatusEx

---

Conclusion

La mémoire sous Windows, c’est :

* un espace virtuel par processus
* un stack par thread
* un heap partagé
* des pages avec des protections strictes

Et si tu maîtrises :

* HeapAlloc/Free
* VirtualAlloc/Protect/Query
* le mapping

tu as déjà un niveau solide en dev système.

A bientôt pour un prochain cours :

Who is online

Users browsing this forum: Hydraxx and 1 guest