0Pricing
C Academy · Leçon

Accès invalide

Dépassements de limites et données non initialisées

Accès invalide est une leçon C Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C Academy comprend 4 leçons au total.

Au-delà des fuites

Les fuites gaspillent de la mémoire, mais les erreurs d'accès invalide la corrompent. memcheck en détecte plusieurs types :

  • Lire ou écrire au-delà de la fin d'un tampon
  • Utiliser de la mémoire après free
  • Lire des valeurs non initialisées
  • Lire ou écrire via un pointeur incorrect

Ces erreurs provoquent les plantages les plus dangereux et les plus difficiles à reproduire.

Écriture hors limites

Ce code alloue de la place pour 5 entiers, mais écrit à l'indice 5, c'est-à-dire dans le sixième emplacement.

L'indice 5 se trouve un élément après la fin. memcheck signale une Invalid write of size 4 à cette ligne.

#include <stdlib.h>

int main(void) {
    int *a = malloc(5 * sizeof(int));
    a[5] = 99; /* valid indices are 0..4 */
    free(a);
    return 0;
}

Lire l'erreur

Le rapport indique l'opération, la taille et la position par rapport au bloc :

Invalid write of size 4
Address 0x... is 0 bytes after a block of size 20 alloc'd

La mention « 0 bytes after a block of size 20 » indique que l'accès s'est produit immédiatement après une allocation de 20 octets (5 entiers).

Lecture hors limites

Les lectures sont également détectées. Ici, la boucle va un élément trop loin.

memcheck signale une Invalid read of size 4 lors de la dernière itération, même si le programme peut sembler « fonctionner » par chance.

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

int main(void) {
    int *a = calloc(3, sizeof(int));
    for (int i = 0; i <= 3; i++)   /* should be i < 3 */
        printf("%d\n", a[i]);
    free(a);
    return 0;
}

Valeurs non initialisées

malloc ne met pas la mémoire à zéro. L'utiliser avant de lui affecter une valeur produit une valeur imprévisible.

memcheck signale Conditional jump or move depends on uninitialised value(s) lorsqu'une telle valeur influence le flux de contrôle ou la sortie.

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

int main(void) {
    int *p = malloc(sizeof(int));
    if (*p == 0)              /* *p was never set */
        printf("zero\n");
    free(p);
    return 0;
}

Pourquoi les rapports sur les valeurs non initialisées sont différés

memcheck ne se plaint pas au moment précis où vous lisez une mémoire non initialisée. Il suit le caractère « défini » des valeurs et ne signale le problème que lorsqu'une valeur indéfinie a réellement de l'importance, par exemple dans une branche, une sortie ou un appel système.

Cela évite les fausses alertes lorsque vous copiez sans conséquence des octets non initialisés.

Utilisation après libération

Accéder à une mémoire après l'avoir libérée constitue un comportement indéfini. memcheck le détecte avec précision.

Il signale Invalid read of size 4 avec la note Address ... is 0 bytes inside a block of size 4 free'd, et indique même où free a été appelé.

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

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 7;
    free(p);
    printf("%d\n", *p);   /* read after free */
    return 0;
}

Double libération

Libérer deux fois le même pointeur corrompt les informations de gestion de l’allocateur.

memcheck signale Invalid free() et affiche à la fois la libération actuelle et l’allocation d’origine, ce qui rend l’erreur évidente.

#include <stdlib.h>

int main(void) {
    int *p = malloc(sizeof(int));
    free(p);
    free(p);   /* freed twice */
    return 0;
}

Suivre les origines

Pour les erreurs liées à des valeurs non initialisées, ajoutez --track-origins=yes.

memcheck indique alors où la mauvaise valeur a été créée, et pas seulement où elle a été utilisée, transformant un avertissement vague en correction précise.

valgrind --track-origins=yes ./prog

Pile et variables globales

memcheck excelle pour les erreurs du tas. Pour les dépassements sur la pile ou dans les tableaux globaux, sa couverture est moins bonne.

Dans ces cas, AddressSanitizer (gcc -fsanitize=address) est souvent le meilleur choix. Les deux outils se complètent.

Dépassement d’une unité : le terminateur nul

Un dépassement fréquent du tas consiste à oublier le terminateur de chaîne. strlen renvoie 5 pour 'hello', mais la chaîne nécessite 6 octets pour stocker le '\0' final.

memcheck signale une écriture invalide lorsque strcpy écrit cet octet final après la fin.

#include <stdlib.h>
#include <string.h>

int main(void) {
    char *s = malloc(strlen("hello")); /* needs +1 */
    strcpy(s, "hello");                 /* writes the '\0' past end */
    free(s);
    return 0;
}

Vérification rapide

Identifiez ce que memcheck signale pour l’extrait.

Récapitulatif

Vous savez maintenant repérer les erreurs d’accès invalides :

  • Les lectures et écritures hors limites apparaissent comme une lecture ou une écriture invalide, avec le décalage dans le bloc
  • Les valeurs non initialisées sont signalées lorsqu’elles influencent une décision ou une sortie
  • Les utilisations après libération et les doubles libérations sont détectées avec les deux emplacements d’appel
  • Utilisez --track-origins=yes pour localiser les valeurs indéfinies ; associez-le à ASan pour les erreurs de pile

Ensuite : lire le rapport complet.

Questions Fréquemment Posées

La leçon « Accès invalide » est-elle gratuite ?

Oui — le texte complet de « Accès invalide » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C Academy, passe à CoddyKit PRO. Le cours C Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Accès invalide » ?

Dépassements de limites et données non initialisées Tu pratiques C Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer C Academy ?

Aucune expérience préalable n'est requise. C Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Accès invalide » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon C Academy ?

Oui. Chaque leçon C Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Pourquoi Valgrind
  2. Détecter les fuites
  3. Accès invalide
  4. Lire les rapports
← Retour à C Academy