IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

FAQ C++ moderne et erreurs courantes

Ce ou ces sujets font partie d'une FAQ en cours d'écriture, vos retours sont les bienvenus.

La fonction retourne l'adresse d'une variable locale

Rappel : une variable dite « locale » est une variable qui est détruite à la fin du scope dans lequel elle a été déclarée.

Que signifie « détruite » ?

En C++, cela conduit d'abord à un appel de son destructeur.

Cela signifie que la zone mémoire où la variable était stockée (et qui lui était jusqu'alors exclusivement réservée) est libérée. Cette zone peut dès lors être réutilisée à tout moment par une autre partie de votre programme pour y stocker une nouvelle variable.

Ayant conservé cette adresse (ou référence [C++]) désormais libérée (on parle dès lors de « dangling pointer/reference »), le danger réside dans son accès, que ce soit pour y lire ou écrire des données.

Un danger qui est amplifié lorsque cette zone n'apparaît pas encore réutilisée et que vous obtenez uniquement par malchance, un programme qui ne plante pas ou se comporte visiblement de façon normale.
Je dis bien par « malchance », car cela rend cette erreur d'autant plus difficile à déceler, et comme tout comportement indéfini, elle attend juste les bonnes conditions pour se manifester.
Je dis bien « apparaît », car en modifiant cette zone vous pouvez très bien modifier de façon totalement imprévisible d'autres variables de votre programme qui occupent dès lors cet emplacement, et inversement.

Exemple de possibilité (qui peut dépendre du compilateur utilisé et/ou des options que vous lui passez) :

 
Sélectionnez
int * get_tab() {
    int tab[10];
    // ...
    return tab;
}
 
Sélectionnez
int *tab = get_tab();
int a = 42;
tab[0] = 100;
Image non disponible
  1. Au début de la fonction get_tab(), le tableau int tab[10] est ajouté à la pile d'exécution.
  2. Mais dès que l'on atteint la fin de la fonction, ce tableau local est détruit et sa zone mémoire libérée.
  3. La nouvelle variable int a = 42; peut alors tout à fait venir prendre la place de sa première case…
  4. … et modifier cette première case tab[0] = 100; entrainera malgré nous également la modification de la valeur de a (et inversement), étant situées à la même adresse.

Que faire ?

Si la variable en question est un tableau :

Dans le cas contraire, vous voudrez probablement effectuer un retour par valeur à la place.

Créé le 17 avril 2018  par Winjerome

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2022 Winjerome. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.