Pointeurs et mémoire

Gestion de la mémoire dynamique en C et C++

Dans cette leçon, vous allez allouer un tableau dont la taille n'est connue qu'à l'exécution, puis libérer cette mémoire en toute sécurité.

Introduction

La mémoire dynamique sert quand la taille ou la durée de vie des données ne peut pas être fixée à la compilation, par exemple quand le nombre d'éléments dépend de ce que tape l'utilisateur. Cette mémoire est allouée pendant l'exécution du programme et doit être libérée quand on n'en a plus besoin.

Points importants

  • Un pointeur ne doit pointer que vers un objet qui existe encore, du bon type, ou valoir null.
  • Chaque zone mémoire allouée doit être libérée exactement une fois.
  • Indiquez clairement quelle fonction possède la mémoire (ownership) et quelles données sont seulement lues (const).

Exemples de code C et C++

C
Exécuter →
main.c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    size_t count = 5;
    int *values = calloc(count, sizeof *values);
    if (!values) return 1;
    for (size_t i = 0; i < count; ++i) values[i] = (int)(i * i);
    printf("last=%d\n", values[count - 1]);
    free(values);
    return 0;
}
Résultat de l’exécution
last=16
C++
Exécuter →
main.cpp
#include <iostream>
#include <vector>

int main() {
    std::vector<int> values(5);
    for (std::size_t i = 0; i < values.size(); ++i) values[i] = static_cast<int>(i * i);
    std::cout << "last=" << values.back() << '\n';
}
Résultat de l’exécution
last=16

Comparaison entre C et C++

En C, calloc alloue la mémoire pour 5 entiers et les initialise à 0. Le programme doit vérifier si l'allocation a échoué et appeler free pour libérer la mémoire à la fin, sinon il y a une fuite de mémoire (memory leak). En C++, std::vector gère lui-même sa mémoire et la libère automatiquement quand il n'est plus utilisé, même si une exception survient.

C

La possession et la libération de la mémoire reposent entièrement sur le programmeur.

C++

Les conteneurs et RAII libèrent automatiquement les ressources quand l'objet arrive en fin de vie.

Exercices d'approfondissement

Exécutez les deux versions, puis modifiez le code pour observer la différence de sécurité qu'apporte chaque langage.

  • Testez avec des pointeurs nuls et des échecs d'allocation mémoire.
  • Exécutez le programme avec AddressSanitizer et UndefinedBehaviorSanitizer pour détecter les erreurs mémoire.
  • Indiquez clairement quel pointeur possède la mémoire et lequel sert seulement à lire.

S'entraîner avec un défi

Utilisez le contenu de cette leçon pour résoudre un vrai problème. Chaque défi s'exécute dans le navigateur, avec des tests instantanés et une revue par l'IA.

Tous les défis