October 1, 20255 min

Stack vs. Heap en Rust: Où Vivent tes Données ?

m
mayo

Rust utilise l'allocation stack et heap pour gérer la mémoire, avec des caractéristiques distinctes pour chacune. Comprendre leurs différences et comment Rust décide où allouer les données est clé pour écrire du code efficace et sûr.

Stack (LIFO, taille fixe) Heap (taille dynamique) let x = 5; (i32) let s = String::from(..) boxed: ptr ● "heap" (octets String) 42 Box::new(42)

Stack vs. Heap en Rust

Stack Heap
Allocation/désallocation rapide (LIFO). Allocation plus lente (dynamique).
Taille fixe, connue au moment de la compilation. Taille peut grandir (ex : String, Vec).
Cleanup automatique (pas de free() nécessaire). Gestion manuelle (via trait Drop).
Utilisé pour types primitifs (i32, bool), petites structs. Utilisé pour données larges, dynamiques (String, Box<T>).

Comment Rust Décide Où Allouer

Par Défaut → Stack

Si un type a une taille fixe (ex : i32, arrays, structs sans String/Vec), il est alloué sur le stack.

Exemple :

let x = 5; // Stack (i32 est taille fixe)

Allocation Heap Explicite

Utilise des types comme Box<T>, String, Vec, etc., pour allouer sur le heap.

Exemple :

let s = String::from("heap"); // Heap (string UTF-8 extensible)
let boxed = Box::new(42);     // Heap (Box<T>)

Move Semantics

Quand une valeur est moved, ses données heap sont transférées, pas copiées, assurant une gestion mémoire efficace.

Exemple :

let s1 = String::from("hello"); // Heap-allocated
let s2 = s1; // Move ownership (données heap pas copiées)
// println!("{}", s1); // ERREUR: s1 est invalidé
Avant Après let s1 = String::from("hello"); let s2 = s1; stack s1 : ptr | len 5 | cap 5 header de 3 mots s1 — moved, inutilisable s2 : ptr | len 5 | cap 5 même ptr, copie bit à bit move heap "hello" "hello" intact — zéro octet copié Un seul owner par buffer : s1 doit être invalidé pour que le bloc heap soit libéré une seule fois.

Points Clés

Stack : Rapide, taille fixe, automatique.
Heap : Flexible, dynamique, manuel (via smart pointers).
✅ Rust privilégie le stack mais utilise le heap pour données extensibles/taille inconnue.

Suivi : Quand forcerais-tu l'allocation heap ?

  • Pour de grosses structs (éviter stack overflow).
  • Quand tu as besoin de dynamic dispatch (ex : Box<dyn Trait>).
  • Pour partager ownership entre threads (Arc<T>).
Retour au blog
Partager ::