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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

problèmes générés par conversion const char* en char*


Sujet :

C++

  1. #1
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    630
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 630
    Points : 234
    Points
    234
    Par défaut problèmes générés par conversion const char* en char*
    Bonjour,
    Dans mon code ( un code que j'ai repris, je n'ai pas le droit de le modifier à priori ), je manipule des char*. afin de concaténer deux char* data1 et data2 j'ai fait appel à std::string puis une fois les deux char* concaténés (data1data2), je les reconvertis avec c_str( ) en const char* data1data2.
    Je dois renvoyer le resultat dans char* data qui est un membre d'une structure info ( info->data = data1data2 ).
    Le problème est que data1data2 est un const char* et donc théoriquement, je n'ai pas le droit de le rabaisser en char *. Mais j'ai fait quand meme un cast à la barbare... :
    info->data = const_cast< char *>(data1data2); et ca passe...

    Mes questions:
    1) face à de telles situations que faut - il faire ? garder le cast ?
    2) quels sont les conséquences d'un tel cast ?

    Merci d'avance pour votrea aide

  2. #2
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 476
    Points
    11 476
    Billets dans le blog
    11
    Par défaut
    Déjà, comme ton const char * vient d'un std::string::c_str(), il ne faut surtout pas le stocker tel quel, mais le copier dans un char * que tu auras alloué auparavant à la bonne taille. Ceci est dû au fait que c_str renvoie probablement (dépend du compilo, en fait) une chaîne temporaire qui sera détruite ou invalidée par la suite. Il faut donc la copier dans un buffer à soi pour être sûr de ne pas avoir de problèmes.
    Ensuite vu que tu utilises std::string pour ta concaténation, pourquoi ne stockes tu pas ce string plutôt qu'un char * ? Ca t'éviterait d'avoir à te poser ce genre de questions, et de faire ce genre d'erreurs.

    Pour répondre à tes questions :
    1) non il ne faut pas faire ce cast dû au problème de c_str.
    2) les conséquences de ce cast seront que selon l'implémentation de c_str, ça crashera lourdement quand tu essaieras de modifier ou même d'accéder à ta chaine.
    De manière générale, le const_cast est à éviter.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Quitte à ne pas faire du C++ correcte en utilisant des char*, autant continuer et utiliser les fonctions C de manipulations de chaines plutôt que de passer par un std::string : utilises strcat

  4. #4
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    630
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 630
    Points : 234
    Points
    234
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    Déjà, comme ton const char * vient d'un std::string::c_str(), il ne faut surtout pas le stocker tel quel, mais le copier dans un char * que tu auras alloué auparavant à la bonne taille. Ceci est dû au fait que c_str renvoie probablement (dépend du compilo, en fait) une chaîne temporaire qui sera détruite ou invalidée par la suite. Il faut donc la copier dans un buffer à soi pour être sûr de ne pas avoir de problèmes.
    la chaine renvoyée par c_str( ) est détruite à quel moment ? Et pourquoi on l'a conçu de telle sorte qu'elle soit invalidée par la suite ... ?
    Dans quelle situation on utilise c_str( ) alors ? parce que si la chaine renvoyée par celle-ci sera invalidée par la suite, je ne vois pas pourquoi j'utiliserais c_str( )
    Ensuite vu que tu utilises std::string pour ta concaténation, pourquoi ne stockes tu pas ce string plutôt qu'un char * ? Ca t'éviterait d'avoir à te poser ce genre de questions, et de faire ce genre d'erreurs.
    je n'ai pas le droit de modifier info->char* , c'est un code que j'ai repris et que est utilié par d'autres couches qui s'attendent à un char*

    Ce code que j'ai repris a un style C, bien que des fonctions c++ soient appelées. ( très peu de classes, plusieurs variables globales, etc ...)

    Comme gbdivers a dit, c'est mieux peut etre de faire un strcat par exemple et de laisser tomber std::string

  5. #5
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par ikuzar Voir le message
    Comme gbdivers a dit, c'est mieux peut etre de faire un strcat par exemple et de laisser tomber std::string
    C'est une question de sensibilité. Moi par exemple, je préfère passer par un string temporaire. Mais c'est tout simplement parce que je maîtrise bien la classe string et que je ne connais pas les fonctions de traitement de chaines en C.

    Pour faire simple, c_str() renvoi un pointeur constant sur le buffer interne de la classe string. Donc si tu assignes ce pointeur à un pointeur p à toi, il faut bien comprendre que dès que l'objet string qui le contient sera détruit, ton pointeur p sera invalide.

    Citation Envoyé par ikuzar
    je n'ai pas le droit de modifier info->char*
    J'imagine que ce que tu veux dire c'est que info->char* est déjà alloué et que ce n'est pas à toi de t'occuper de la mémoire. J'espère que tu connais la taille qui lui a été alloué. Enfin bref, cela signifie surtout que de toutes façons, quelle que soit la méthode que tu choisi, il te faut faire une copie. Et pas une copie de pointeur (const char* toto = ma_string.c_str(), avec ou sans const_cast, est une copie de pointeur). En c++, pour faire des copies entre conteneurs, on utilise la fonction copy() (définie dans l'en-tête <algorithm>).
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  6. #6
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    630
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 630
    Points : 234
    Points
    234
    Par défaut
    dans strcat(char* dest, char* src ) est ce que dest doit se temriner par un \0 ? Si dest ne se terine pas par \0 est ce que strcat se comporte comme si il y avait un \0 à la fin de "dest", c'est à dire il n'écrase pas le dernier caractère de "dest" ?

  7. #7
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    C'est une question de sensibilité. Moi par exemple, je préfère passer par un string temporaire. Mais c'est tout simplement parce que je maîtrise bien la classe string et que je ne connais pas les fonctions de traitement de chaines en C.
    Je suis d'accord avec toi et je fais comme ça habituellement quand je dois récupérer ou envoyer un char* dans une lib C.
    Mais dans ce cas, il faut récupérer des char* et renvoyer des char*. C'est un peu lourd de passer par un string.

    Avec du code C :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* result = stdcat(data1, data2);
    Avec du code C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    string str = string(data1) + string(data2);
    char* result = new char[str.size()];
    copy(str.begin(), str.end(), result);
    C'est un peu lourd quand même...

    dans strcat(char* dest, char* src ) est ce que dest doit se temriner par un \0 ? Si dest ne se terine pas par \0 est ce que strcat se comporte comme si il y avait un \0 à la fin de "dest", c'est à dire il n'écrase pas le dernier caractère de "dest" ?
    Une chaine char* doit toujours se terminer par un '\0'. Je te renvois à la FAQ C pour les explications

  8. #8
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Ha oui effectivement. Un peu de code vaut mieux que beaucoup de commentaires
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

Discussions similaires

  1. Conversion const char* vers std::string
    Par scheme dans le forum C++
    Réponses: 4
    Dernier message: 21/09/2010, 11h02
  2. Problème conversion const char *
    Par autoz dans le forum Débuter
    Réponses: 5
    Dernier message: 15/10/2009, 21h19
  3. Réponses: 7
    Dernier message: 16/02/2008, 07h30
  4. Problème de conversion de CString en char *
    Par vonemya dans le forum C++
    Réponses: 6
    Dernier message: 11/09/2007, 15h38
  5. error: invalid conversion from `const wxChar*' to `CHAR*'
    Par barbarello dans le forum wxWidgets
    Réponses: 16
    Dernier message: 31/01/2006, 11h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo