cours La mémoire : qui possède quoi 2/5

Un octet de trop

Les tests passent, le sanitizer hurle. Il manque un octet pour le terminateur.

Leçon

L'idée : une chaîne cache un octet

Une chaîne C de n caractères occupe n + 1 octets. Le dernier est le terminateur '\0'. strlen ne le compte pas, et malloc ne l'ajoute pas à votre place.

Écrire un octet après la fin d'un bloc est un débordement de tas (heap buffer overflow). Ça « marche » souvent : l'octet tombe dans du padding, les tests restent verts et la corruption attend un mauvais jour.

La situation

upper_copy renvoie une copie en majuscules d'une chaîne. Lancez les tests : ils passent. Lancez maintenant le sanitizer : lui, non.

Votre mission

Lisez le rapport du sanitizer : il nomme le bloc débordé, la ligne où il a été alloué et la fonction qui a écrit après sa fin. Comparez le nombre d'octets alloués au nombre d'octets écrits. Donnez ensuite au junior l'arithmétique exacte.

À surveiller

  • Des tests verts ne prouvent rien sur la sûreté mémoire. Les deux outils doivent être propres.
  • « Alloue plus » est tentant. Est-ce valable pour toutes les longueurs ? Pensez à la chaîne vide.

Essayez cet exercice

Créez un compte gratuit pour dire au junior IA quoi changer, lancer les tests et le vérificateur mémoire, et obtenir un code de complétion vérifiable.

Code de départ
upper.c
#include "upper.h"#include <ctype.h>#include <stdlib.h>#include <string.h> char *upper_copy(const char *s) {    size_t n = strlen(s);    char *out = malloc(n);    if (!out) return NULL;    for (size_t i = 0; i < n; i++) {        out[i] = (char)toupper((unsigned char)s[i]);    }    out[n] = '\0';    return out;}
upper.h
#ifndef UPPER_H#define UPPER_H/* Returns a new heap string with every letter upper-cased. The CALLER owns the result. */char *upper_copy(const char *s);#endif