Dessine-moi Rust 🦀

Enfin pas tout

Nous n'avons que 45 min 😅

@_Akanoa_

https://lafor.ge

Comment Rust gère la libération de la mémoire ?

Un peu de bas niveau

0️⃣ 1️⃣ 0️⃣
1️⃣ 0️⃣ 1️⃣

1️⃣ 0️⃣ 0️⃣

Architecture Von Neumann (très) simplifiée

Partitionnement de la mémoire

Segmentation de la mémoire

Différents usages de la mémoire

Mécanisme de libération de la mémoire

Pointeurs

Le problème de la Heap 🤔

#include <stdio.h>
#include <stdlib.h>

void greedy(int i) {

    // On demande de la mémoire
    int *p = malloc(sizeof(int));

    if (p != NULL) {
        *p = i;
    }
    // Mais on ne la libère pas
}

int main() {

    for (int i = 0; i < 1000000000; i++) {
        greedy(i);
    }

    return 0;
}

Libération mémoire 🧹

void ungreedy(int i) {

    // On demande de la mémoire
    int *p = malloc(sizeof(int));

    if (p != NULL) {
        *p = i;
    }
    // libération de la mémoire détenu par par p
    free(p);
}

Choisir son poison 🧪

Libération manuelle 🖐️

Garbage Collector 🤖

Free Explicite 🖐️✏️ Garbage Collector 🤖
❌ Double Free ‼️ ✅ Automatique
    - pas d'oublie de free
    - pas de early free
    - pas de double free
❌ Leak (oublie) 🤭 📈 ❌ Freezes réguliers ❄️
❌ Early ( Segfault ) 🐇 💥 ❌ Tuning compliqué 🧙🏼‍♀️
❌ Complexe 🤯 😐 Side-car
✅ Très performant ⚡
À la compilation ⚙️ Pendant l'exécution 🏃

La 3ème Voie

Borrow Checker  🦀

  • Très performant ⚡
  • Automatique 🤖
    • pas de double free ‼️
    • pas de early free 🐇 💥
    • pas d'oublie de free 🤭 📈
  • Pas de Garbage Collector 🚮

Enfin du Rust !!

struct Toto {
  data : String
}

impl Toto {
  fn new() -> Self {
    Toto { data : String::new() }
  }
}

impl Drop for Toto {
  fn drop(&mut self) {
    println!("Toto doit mourir")
  }
}
Hello world!
Toto doit mourir
fn main() {
    let toto = Toto::new();
    println!("Hello world!");
}

Tout est question de contexte

fn main() {
  let toto = Toto::new();
  eat(toto);
  println!("Fin du programme");
}

fn eat(toto: Toto) {
  println!("Dans la fonction eat");
}
Dans la fonction eat
Toto doit mourir
Fin du programme

L'Attaque des Clones

Question de propriété

fn main() {
    let toto = Toto::new();
    let toto2 = 
        give_back(toto);
    println!("Hello world!");
}

fn give_back(toto: Toto) 
  -> Toto 
{
    println!("Give back!");
    toto
}
Give back!
Hello world!
Toto doit mourir

Prêt de data

fn main() {
    let toto = Toto::new();
    lend(&toto);
    println!("Hello world!");
}

fn lend(toto: &Toto) {
    println!("Lend!")
}
Lend!
Hello World!
Toto est détruit

Prêt multiple

fn main() {
    let toto = Toto::new();
    lend(&toto);
    lend(&toto);
    println!("Hello world!");
}
Lend!
Lend!
Hello world!
Toto est détruit

Borrow Checker 👩🏿‍⚖️

fn main() {
    let toto = Toto::new();
    let toto_ref = &toto;
    drop(toto);
    lend(toto_ref);
}

fn lend(toto: &Toto) {
    println!("Lend!")
}

Merci à toutes et tous 😃

@_Akanoa_

https://lafor.ge