Pointeurs et mémoire

Bien utiliser const en C et C++

Dans cette leçon, vous allez utiliser le mot-clé const pour déclarer des données en lecture seule et distinguer les différentes façons de combiner const et pointeurs.

Introduction

Le mot-clé const permet à une fonction de s'engager à ne pas modifier les données qu'elle reçoit. Si quelqu'un modifie par erreur une donnée marquée const, le compilateur signale immédiatement l'erreur. Le code est ainsi plus sûr, et le lecteur voit facilement quelles fonctions ont le droit de modifier les données.

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>

int sum(const int *values, size_t count) {
    int total = 0;
    for (size_t i = 0; i < count; ++i) total += values[i];
    return total;
}

int main(void) {
    const int values[] = {2, 4, 6};
    printf("%d\n", sum(values, 3));
    return 0;
}
Résultat de l’exécution
12
C++
Exécuter →
main.cpp
#include <array>
#include <iostream>

int sum(const std::array<int, 3>& values) {
    int total = 0;
    for (int value : values) total += value;
    return total;
}

int main() {
    const std::array values{2, 4, 6};
    std::cout << sum(values) << '\n';
}
Résultat de l’exécution
12

Comparaison entre C et C++

Le paramètre const int *values indique que la fonction sum lit les éléments du tableau sans les modifier. Lisez la déclaration en partant du nom de la variable : un pointeur vers des données const (const int *) protège la valeur pointée, tandis qu'un pointeur const (int * const) ne peut pas pointer vers une autre adresse. C++ a aussi les fonctions membres const, qui s'engagent à ne pas modifier l'état de l'objet.

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.