Conversion piégeuse
Par Cédric Tabin le jeudi 30.06.2011, 08:00 - C/C++ - Lien permanent
Quel est le problème dans ce bloc de code C++ ?
#include <stdio.h> #include <sstream> int main() { std::ostringstream oss; oss << 42; const char* value = oss.str().c_str(); printf("value: %s\n", value); return 0; }
L'output de ce programme est bien 42 ! Qu'en est-il de celui-ci ?
#include <stdio.h> #include <sstream> int main() { std::ostringstream oss; oss << 42; const char* value = oss.str().c_str(); std::string x = "abc"; printf("value: %s\n", value); return 0; }
Aucun changement ? Et pourtant ce programme affiche un royal abc ! Cela vient du fait qu'il faut se méfier des raccourcis (spécialement) en C++. Ce comportement singulier est provoqué par la ligne suivante:
const char* value = oss.str().c_str();
Après que ce code a été exécuté, la variable value contient un dangling pointer ! La méthode str() renvoie bien une instance copiée de std::string mais qui n'est valide que durant le scope de l'affectation (une fois la ligne exécutée, cette instance sera détruite). Le deuxième point est que la fonction c_str() retourne un pointeur interne et donc si l'instance est détuite, cette mémoire est également libérée.
Pour se dégourdir les neurones, il y a ce test un peu plus poussif !